Skip to content

Commit 41bf3bf

Browse files
committed
display: optimize grayscale image display
suggested-by: Larry Bank <bitbank@pobox.com>
1 parent 71280e5 commit 41bf3bf

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

main/display.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -880,14 +880,23 @@ void display_print_in_area(const char* st, int x, int y, dispWin_t areaWin, bool
880880
}
881881
}
882882

883-
#define GRAY_MASK1 0xF8
884-
#define GRAY_MASK2 0xFC
885-
886-
static inline uint16_t uint8_to_uint16_color(uint8_t gray)
887-
{
888-
const uint16_t res = ((gray & GRAY_MASK1) << 8) | ((gray & GRAY_MASK2) << 3) | ((gray & GRAY_MASK1) >> 3);
889-
return __builtin_bswap16(res);
890-
}
883+
// Macros to convert a grayscale 0-255 index to big-endian 565 RGB
884+
#define GS_MASK1 0xF8
885+
#define GS_MASK2 0xFC
886+
#define GS_CPU(n) (((n & GS_MASK1) << 8) | ((n & GS_MASK2) << 3) | ((n & GS_MASK1) >> 3))
887+
// TODO: this should just be GS_CPU(n) if our arch is natively big-endian
888+
#define GS(n) ((GS_CPU(n) & 0x00ff) << 8) | ((GS_CPU(n) & 0xff00) >> 8)
889+
890+
// We have 6 bits max per R/G/B, so only need 64 distinct mappings
891+
static const uint16_t gray_565[64] = { GS(0), GS(4), GS(8), GS(12), GS(16), GS(20), GS(24), GS(28), GS(32), GS(36),
892+
GS(40), GS(44), GS(48), GS(52), GS(56), GS(60), GS(64), GS(68), GS(72), GS(76), GS(80), GS(84), GS(88), GS(92),
893+
GS(96), GS(100), GS(104), GS(108), GS(112), GS(116), GS(120), GS(124), GS(128), GS(132), GS(136), GS(140), GS(144),
894+
GS(148), GS(152), GS(156), GS(160), GS(164), GS(168), GS(172), GS(176), GS(180), GS(184), GS(188), GS(192), GS(196),
895+
GS(200), GS(204), GS(208), GS(212), GS(216), GS(220), GS(224), GS(228), GS(232), GS(236), GS(240), GS(244), GS(248),
896+
GS(252) };
897+
898+
#undef GS_CPU
899+
#undef GS
891900

892901
void display_picture(const Picture* imgbuf, int x, int y, dispWin_t area)
893902
{
@@ -942,11 +951,15 @@ void display_picture(const Picture* imgbuf, int x, int y, dispWin_t area)
942951
color_t* hw_buf = display_hw_get_buffer();
943952
const int offsetx = calculatedx - CONFIG_DISPLAY_OFFSET_X;
944953
const int offsety = calculatedy - CONFIG_DISPLAY_OFFSET_Y;
945-
uint16_t* screen_ptr = &hw_buf[offsetx + offsety * CONFIG_DISPLAY_WIDTH];
954+
uint16_t* disp_ptr = &hw_buf[offsetx + offsety * CONFIG_DISPLAY_WIDTH];
955+
const uint8_t* src_ptr = imgbuf->data_8;
956+
const uint16_t stride = CONFIG_DISPLAY_WIDTH - imgbuf->width;
946957
for (size_t i = 0; i < imgbuf->height; ++i) {
947958
for (size_t k = 0; k < imgbuf->width; ++k) {
948-
screen_ptr[k + i * CONFIG_DISPLAY_WIDTH] = uint8_to_uint16_color(imgbuf->data_8[k + imgbuf->width * i]);
959+
*disp_ptr++ = gray_565[*src_ptr >> 2];
960+
++src_ptr;
949961
}
962+
disp_ptr += stride;
950963
}
951964
#else
952965

@@ -960,7 +973,8 @@ void display_picture(const Picture* imgbuf, int x, int y, dispWin_t area)
960973
const uint8_t* src_ptr = imgbuf->data_8 + line_offset * imgbuf->width;
961974

962975
for (int i = 0; i < maximum_lines * imgbuf->width; ++i) {
963-
*disp_ptr++ = uint8_to_uint16_color(*src_ptr++);
976+
*disp_ptr++ = gray_565[*src_ptr >> 2];
977+
++src_ptr;
964978
}
965979

966980
draw_bitmap(calculatedx, calculatedy + line_offset, imgbuf->width, maximum_lines, disp_buf);

0 commit comments

Comments
 (0)