diff mbox

[1/2] drm/udl: optimize udl_compress_hline16

Message ID 1422468930-20592-1-git-send-email-hshi@chromium.org (mailing list archive)
State New, archived
Headers show

Commit Message

Haixia Shi Jan. 28, 2015, 6:15 p.m. UTC
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: Haixia Shi <hshi@chromium.org>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Tested-by: Haixia Shi <hshi@chromium.org>
---
 drivers/gpu/drm/udl/udl_transfer.c | 41 +++++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 21 deletions(-)

Comments

Chris Wilson Jan. 28, 2015, 9:12 p.m. UTC | #1
On Wed, Jan 28, 2015 at 10:15:29AM -0800, Haixia Shi wrote:
> 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: Haixia Shi <hshi@chromium.org>
> Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
> Tested-by: Haixia Shi <hshi@chromium.org>

This is not based on upstream code, similar but it won't apply.
-Chris
Haixia Shi Jan. 28, 2015, 9:50 p.m. UTC | #2
Sorry about that; I have just re-sent the patches based on upstream code.

On Wed, Jan 28, 2015 at 1:12 PM, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> On Wed, Jan 28, 2015 at 10:15:29AM -0800, Haixia Shi wrote:
>> 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: Haixia Shi <hshi@chromium.org>
>> Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
>> Tested-by: Haixia Shi <hshi@chromium.org>
>
> This is not based on upstream code, similar but it won't apply.
> -Chris
>
> --
> Chris Wilson, Intel Open Source Technology Centre
diff mbox

Patch

diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c
index f343db7..eadddf9 100644
--- a/drivers/gpu/drm/udl/udl_transfer.c
+++ b/drivers/gpu/drm/udl/udl_transfer.c
@@ -82,12 +82,14 @@  static inline u16 pixel32_to_be16(const uint32_t pixel)
 		((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)
-		return *(const uint16_t *)pixel == repeat;
-	else
-		return *(const uint32_t *)pixel == repeat;
+		pixel_val16 = *(uint16_t *)pixel;
+	else if (bpp == 4)
+		pixel_val16 = pixel32_to_be16p(pixel);
+	return pixel_val16;
 }
 
 /*
@@ -134,6 +136,7 @@  static void udl_compress_hline16(
 		uint8_t *cmd_pixels_count_byte = NULL;
 		const u8 *raw_pixel_start = NULL;
 		const u8 *cmd_pixel_start, *cmd_pixel_end = NULL;
+		uint16_t pixel_val16;
 
 		prefetchw((void *) cmd); /* pull in one cache line at least */
 
@@ -154,33 +157,29 @@  static void udl_compress_hline16(
 			    (int)(cmd_buffer_end - cmd) / 2))) * bpp;
 
 		prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp);
+		pixel_val16 = get_pixel_val16(pixel, bpp);
 
 		while (pixel < cmd_pixel_end) {
-			const u8 *const start = pixel;
-			u32 repeating_pixel;
-
-			if (bpp == 2) {
-				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));
-			}
+			const u8 * const repeating_pixel = pixel;
+			const uint16_t repeating_pixel_val16 = pixel_val16;
+
+			*(uint16_t *)cmd = cpu_to_be16(pixel_val16);
 
 			cmd += 2;
 			pixel += bpp;
 
-			if (unlikely((pixel < cmd_pixel_end) &&
-				     (pixel_repeats(pixel, repeating_pixel, bpp)))) {
+			while (pixel < cmd_pixel_end) {
+				pixel_val16 = get_pixel_val16(pixel, bpp);
+				if (pixel_val16 != repeating_pixel_val16)
+					break;
+				pixel += bpp;
+			}
+
+			if (unlikely(pixel > repeating_pixel + bpp)) {
 				/* go back and fill in raw pixel count */
 				*raw_pixels_count_byte = (((start -
 						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 */
 				*cmd++ = (((pixel - start) / bpp) - 1) & 0xFF;