-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Open
Description
I used a monochrome screen to draw a 200*180 bitmap and noticed that the screen refresh was quite laggy. Later, when I looked at the source code, I found that u8g2_DrawBitmap was drawing pixel by pixel. So, I optimized it using run-length encoding.
void u8g2_DrawHorizontalBitmap_RLE(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b)
{
uint8_t mask;
uint8_t color = u8g2->draw_color;
uint8_t ncolor = (color == 0 ? 1 : 0);
u8g2_uint_t run_x = x; // The starting x-coordinate of the current continuous segment
u8g2_uint_t run_len = 0; // The length of consecutive identical pixels
uint8_t cur_draw_type = 0; // Current pixel type: 0 = Transparent, 1 = Target color, 2 = Inverse color
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
mask = 128;
while(len > 0)
{
uint8_t pixel_draw_type = 0;
if ( *b & mask ) {
pixel_draw_type = 1;
} else {
if ( u8g2->bitmap_transparency == 0 ) {
pixel_draw_type = 2;
} else {
pixel_draw_type = 0;
}
}
// Determine whether the current pixel is of the same type as the previous segment.
if (pixel_draw_type == cur_draw_type) {
run_len++;
} else {
// Type inconsistency → First draw the consecutive pixels of the previous section, then reset the statistics
if (run_len > 0 && cur_draw_type != 0) {
u8g2->draw_color = (cur_draw_type == 1) ? color : ncolor;
u8g2_DrawHVLine(u8g2, run_x, y, run_len, 0);
}
// Reset the statistics
cur_draw_type = pixel_draw_type;
run_x = x;
run_len = 1; // The current pixel serves as the first pixel of the new segment.
}
// Move to the next pixel
x++;
mask >>= 1;
if ( mask == 0 )
{
mask = 128;
b++;
}
len--;
}
// Process the last continuous group of pixels that have not been drawn.
if (run_len > 0 && cur_draw_type != 0) {
u8g2->draw_color = (cur_draw_type == 1) ? color : ncolor;
u8g2_DrawHVLine(u8g2, run_x, y, run_len, 0);
}
u8g2->draw_color = color;
}Replace u8g2_DrawHorizontalBitmap
void u8g2_DrawBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t cnt, u8g2_uint_t h, const uint8_t *bitmap)
{
u8g2_uint_t w;
w = cnt;
w *= 8;
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
while( h > 0 )
{
//u8g2_DrawHorizontalBitmap(u8g2, x, y, w, bitmap);
// RLE Optimize
u8g2_DrawHorizontalBitmap_RLE(u8g2, x, y, w, bitmap);
bitmap += cnt;
y++;
h--;
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels