提交 86584444 编写于 作者: H Haixia Shi 提交者: Dave Airlie

drm/udl: optimize udl_compress_hline16 (v2)

The run-length encoding algorithm should compare 16-bit encoded pixel
values instead of comparing raw pixel values. It allows pixels
with similar but different colors to be encoded as repeat pixels, and
thus potentially save USB bandwidth.
Signed-off-by: NHaixia Shi <hshi@chromium.org>
Reviewed-by: NDaniel Kurtz <djkurtz@chromium.org>
Tested-by: NHaixia Shi <hshi@chromium.org>
Signed-off-by: NDave Airlie <airlied@gmail.com>
上级 e4100553
...@@ -82,12 +82,14 @@ static inline u16 pixel32_to_be16(const uint32_t pixel) ...@@ -82,12 +82,14 @@ static inline u16 pixel32_to_be16(const uint32_t pixel)
((pixel >> 8) & 0xf800)); ((pixel >> 8) & 0xf800));
} }
static bool pixel_repeats(const void *pixel, const uint32_t repeat, int bpp) static inline u16 get_pixel_val16(const uint8_t *pixel, int bpp)
{ {
u16 pixel_val16 = 0;
if (bpp == 2) if (bpp == 2)
return *(const uint16_t *)pixel == repeat; pixel_val16 = *(const uint16_t *)pixel;
else else if (bpp == 4)
return *(const uint32_t *)pixel == repeat; pixel_val16 = pixel32_to_be16(*(const uint32_t *)pixel);
return pixel_val16;
} }
/* /*
...@@ -134,6 +136,7 @@ static void udl_compress_hline16( ...@@ -134,6 +136,7 @@ static void udl_compress_hline16(
uint8_t *cmd_pixels_count_byte = NULL; uint8_t *cmd_pixels_count_byte = NULL;
const u8 *raw_pixel_start = NULL; const u8 *raw_pixel_start = NULL;
const u8 *cmd_pixel_start, *cmd_pixel_end = NULL; const u8 *cmd_pixel_start, *cmd_pixel_end = NULL;
uint16_t pixel_val16;
prefetchw((void *) cmd); /* pull in one cache line at least */ prefetchw((void *) cmd); /* pull in one cache line at least */
...@@ -154,33 +157,29 @@ static void udl_compress_hline16( ...@@ -154,33 +157,29 @@ static void udl_compress_hline16(
(int)(cmd_buffer_end - cmd) / 2))) * bpp; (int)(cmd_buffer_end - cmd) / 2))) * bpp;
prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp); prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp);
pixel_val16 = get_pixel_val16(pixel, bpp);
while (pixel < cmd_pixel_end) { while (pixel < cmd_pixel_end) {
const u8 *const start = pixel; const u8 *const start = pixel;
u32 repeating_pixel; const uint16_t repeating_pixel_val16 = pixel_val16;
if (bpp == 2) { *(uint16_t *)cmd = cpu_to_be16(pixel_val16);
repeating_pixel = *(uint16_t *)pixel;
*(uint16_t *)cmd = cpu_to_be16(repeating_pixel);
} else {
repeating_pixel = *(uint32_t *)pixel;
*(uint16_t *)cmd = cpu_to_be16(pixel32_to_be16(repeating_pixel));
}
cmd += 2; cmd += 2;
pixel += bpp; pixel += bpp;
if (unlikely((pixel < cmd_pixel_end) && while (pixel < cmd_pixel_end) {
(pixel_repeats(pixel, repeating_pixel, bpp)))) { pixel_val16 = get_pixel_val16(pixel, bpp);
if (pixel_val16 != repeating_pixel_val16)
break;
pixel += bpp;
}
if (unlikely(pixel > start + bpp)) {
/* go back and fill in raw pixel count */ /* go back and fill in raw pixel count */
*raw_pixels_count_byte = (((start - *raw_pixels_count_byte = (((start -
raw_pixel_start) / bpp) + 1) & 0xFF; raw_pixel_start) / bpp) + 1) & 0xFF;
while ((pixel < cmd_pixel_end) &&
(pixel_repeats(pixel, repeating_pixel, bpp))) {
pixel += bpp;
}
/* immediately after raw data is repeat byte */ /* immediately after raw data is repeat byte */
*cmd++ = (((pixel - start) / bpp) - 1) & 0xFF; *cmd++ = (((pixel - start) / bpp) - 1) & 0xFF;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册