1From b276d982a27c421495582b120b0215ad578b7367 Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Mon, 4 Nov 2019 11:11:59 +0800 4Subject: [PATCH 2/6] Support PIXMAN_nv12 format 5 6Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 7--- 8 pixman/pixman-access.c | 86 ++++++++++++++++++++++++++++++++++++++++++ 9 pixman/pixman.c | 3 +- 10 pixman/pixman.h | 6 ++- 11 3 files changed, 93 insertions(+), 2 deletions(-) 12 13diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c 14index 7c5ce78..1e5c0ba 100644 15--- a/pixman/pixman-access.c 16+++ b/pixman/pixman-access.c 17@@ -192,6 +192,25 @@ 18 ((uint8_t *) ((bits) + offset0 + \ 19 ((stride) >> 1) * ((line) >> 1))) 20 21+/* 22+ * NV12 setup and access macros 23+ */ 24+ 25+#define NV12_SETUP(image) \ 26+ bits_image_t *__bits_image = (bits_image_t *)image; \ 27+ uint32_t *bits = __bits_image->bits; \ 28+ int stride = __bits_image->rowstride; \ 29+ int offset0 = stride < 0 ? \ 30+ (-stride) * ((__bits_image->height - 1) >> 1) - stride : \ 31+ stride * __bits_image->height 32+ 33+#define NV12_Y(line) \ 34+ ((uint8_t *) ((bits) + (stride) * (line))) 35+ 36+#define NV12_UV(line) \ 37+ ((uint8_t *) ((bits) + offset0 + \ 38+ (stride) * ((line) >> 1))) 39+ 40 /* Misc. helpers */ 41 42 static force_inline void 43@@ -845,6 +864,42 @@ fetch_scanline_yv12 (bits_image_t *image, 44 } 45 } 46 47+static void 48+fetch_scanline_nv12 (bits_image_t *image, 49+ int x, 50+ int line, 51+ int width, 52+ uint32_t * buffer, 53+ const uint32_t *mask) 54+{ 55+ NV12_SETUP (image); 56+ uint8_t *y_line = NV12_Y (line); 57+ uint8_t *uv_line = NV12_UV (line); 58+ int i; 59+ 60+ for (i = 0; i < width; i++) 61+ { 62+ int16_t y, u, v; 63+ int32_t r, g, b; 64+ 65+ y = y_line[x + i] - 16; 66+ u = uv_line[(x + i) & -2] - 128; 67+ v = uv_line[((x + i) & -2) + 1] - 128; 68+ 69+ /* R = 1.164(Y - 16) + 1.596(V - 128) */ 70+ r = 0x012b27 * y + 0x019a2e * v; 71+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ 72+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; 73+ /* B = 1.164(Y - 16) + 2.018(U - 128) */ 74+ b = 0x012b27 * y + 0x0206a2 * u; 75+ 76+ *buffer++ = 0xff000000 | 77+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | 78+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | 79+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); 80+ } 81+} 82+ 83 /**************************** Pixel wise fetching *****************************/ 84 85 #ifndef PIXMAN_FB_ACCESSORS 86@@ -1036,6 +1091,32 @@ fetch_pixel_yv12 (bits_image_t *image, 87 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); 88 } 89 90+static uint32_t 91+fetch_pixel_nv12 (bits_image_t *image, 92+ int offset, 93+ int line) 94+{ 95+ NV12_SETUP (image); 96+ int16_t y = NV12_Y (line)[offset] - 16; 97+ int16_t u = NV12_UV (line)[offset & -2] - 128; 98+ int16_t v = NV12_UV (line)[(offset & -2) + 1] - 128; 99+ int32_t r, g, b; 100+ 101+ /* R = 1.164(Y - 16) + 1.596(V - 128) */ 102+ r = 0x012b27 * y + 0x019a2e * v; 103+ 104+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ 105+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; 106+ 107+ /* B = 1.164(Y - 16) + 2.018(U - 128) */ 108+ b = 0x012b27 * y + 0x0206a2 * u; 109+ 110+ return 0xff000000 | 111+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | 112+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | 113+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); 114+} 115+ 116 /*********************************** Store ************************************/ 117 118 #ifndef PIXMAN_FB_ACCESSORS 119@@ -1509,6 +1590,11 @@ static const format_info_t accessors[] = 120 fetch_pixel_yv12, fetch_pixel_generic_float, 121 NULL, NULL }, 122 123+ { PIXMAN_nv12, 124+ fetch_scanline_nv12, fetch_scanline_generic_float, 125+ fetch_pixel_nv12, fetch_pixel_generic_float, 126+ NULL, NULL }, 127+ 128 { PIXMAN_null }, 129 }; 130 131diff --git a/pixman/pixman.c b/pixman/pixman.c 132index c09b528..d8a2d24 100644 133--- a/pixman/pixman.c 134+++ b/pixman/pixman.c 135@@ -1070,6 +1070,7 @@ pixman_format_supported_source (pixman_format_code_t format) 136 /* YUV formats */ 137 case PIXMAN_yuy2: 138 case PIXMAN_yv12: 139+ case PIXMAN_nv12: 140 return TRUE; 141 142 default: 143@@ -1092,7 +1093,7 @@ PIXMAN_EXPORT pixman_bool_t 144 pixman_format_supported_destination (pixman_format_code_t format) 145 { 146 /* YUV formats cannot be written to at the moment */ 147- if (format == PIXMAN_yuy2 || format == PIXMAN_yv12) 148+ if (format == PIXMAN_yuy2 || format == PIXMAN_yv12 || format == PIXMAN_nv12) 149 return FALSE; 150 151 return pixman_format_supported_source (format); 152diff --git a/pixman/pixman.h b/pixman/pixman.h 153index 08303b5..3bb2fa5 100644 154--- a/pixman/pixman.h 155+++ b/pixman/pixman.h 156@@ -861,6 +861,9 @@ struct pixman_indexed 157 #define PIXMAN_TYPE_ARGB_SRGB 10 158 #define PIXMAN_TYPE_RGBA_FLOAT 11 159 160+/* HACK: Use maximum value to avoid conflict */ 161+#define PIXMAN_TYPE_NV12 0x3f 162+ 163 #define PIXMAN_FORMAT_COLOR(f) \ 164 (PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \ 165 PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR || \ 166@@ -941,7 +944,8 @@ typedef enum { 167 168 /* YUV formats */ 169 PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0), 170- PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0) 171+ PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0), 172+ PIXMAN_nv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_NV12,0,0,0,0), 173 } pixman_format_code_t; 174 175 /* Querying supported format values. */ 176-- 1772.20.1 178 179