1From 4371f386630d35b6b85d1623f3d988cc0e5ffceb Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Thu, 7 Jul 2022 11:09:23 +0800
4Subject: [PATCH 74/79] gl-renderer: Support more SHM RGB formats
5
6Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
7---
8 libweston/renderer-gl/fragment.glsl          | 21 +++++-
9 libweston/renderer-gl/gl-renderer-internal.h | 11 ++-
10 libweston/renderer-gl/gl-renderer.c          | 71 ++++++++++++++++++++
11 libweston/renderer-gl/gl-shaders.c           | 17 +++++
12 4 files changed, 116 insertions(+), 4 deletions(-)
13
14diff --git a/libweston/renderer-gl/fragment.glsl b/libweston/renderer-gl/fragment.glsl
15index cfadb88..4414b63 100644
16--- a/libweston/renderer-gl/fragment.glsl
17+++ b/libweston/renderer-gl/fragment.glsl
18@@ -46,6 +46,12 @@
19 #define SHADER_COLOR_CURVE_IDENTITY 0
20 #define SHADER_COLOR_CURVE_LUT_3x1D 1
21
22+/* enum gl_shader_color_swap */
23+#define SHADER_COLOR_SWAP_NONE  0
24+#define SHADER_COLOR_SWAP_RGB   1
25+#define SHADER_COLOR_SWAP_ALPHA 2
26+#define SHADER_COLOR_SWAP_ALL   3
27+
28 #if DEF_VARIANT == SHADER_VARIANT_EXTERNAL
29 #extension GL_OES_EGL_image_external : require
30 #endif
31@@ -62,6 +68,7 @@ precision HIGHPRECISION float;
32  * These undeclared identifiers will be #defined by a runtime generated code
33  * snippet.
34  */
35+compile_const int c_color_swap = DEF_COLOR_SWAP;
36 compile_const int c_variant = DEF_VARIANT;
37 compile_const bool c_input_is_premult = DEF_INPUT_IS_PREMULT;
38 compile_const bool c_green_tint = DEF_GREEN_TINT;
39@@ -124,13 +131,11 @@ sample_input_texture()
40 		return unicolor;
41
42 	if (c_variant == SHADER_VARIANT_RGBA ||
43+	    c_variant == SHADER_VARIANT_RGBX ||
44 	    c_variant == SHADER_VARIANT_EXTERNAL) {
45 		return texture2D(tex, v_texcoord);
46 	}
47
48-	if (c_variant == SHADER_VARIANT_RGBX)
49-		return vec4(texture2D(tex, v_texcoord).rgb, 1.0);
50-
51 	/* Requires conversion to RGBA */
52
53 	if (c_variant == SHADER_VARIANT_Y_U_V) {
54@@ -218,6 +223,16 @@ main()
55 	/* Electrical (non-linear) RGBA values, may be premult or not */
56 	color = sample_input_texture();
57
58+	if (c_color_swap == SHADER_COLOR_SWAP_RGB)
59+		color.bgr = color.rgb;
60+	else if (c_color_swap == SHADER_COLOR_SWAP_ALPHA)
61+		color.argb = color;
62+	else if (c_color_swap == SHADER_COLOR_SWAP_ALL)
63+		color.abgr = color;
64+
65+	if (c_variant == SHADER_VARIANT_RGBX)
66+		color.a = 1.0;
67+
68 	if (c_need_color_pipeline) {
69 		/* Ensure straight alpha */
70 		if (c_input_is_premult) {
71diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h
72index ebeaadb..441f154 100644
73--- a/libweston/renderer-gl/gl-renderer-internal.h
74+++ b/libweston/renderer-gl/gl-renderer-internal.h
75@@ -56,6 +56,14 @@ enum gl_shader_color_curve {
76 	SHADER_COLOR_CURVE_LUT_3x1D,
77 };
78
79+/* Keep the following in sync with fragment.glsl. */
80+enum gl_shader_color_swap {
81+	SHADER_COLOR_SWAP_NONE = 0,
82+	SHADER_COLOR_SWAP_RGB,
83+	SHADER_COLOR_SWAP_ALPHA,
84+	SHADER_COLOR_SWAP_ALL,
85+};
86+
87 /** GL shader requirements key
88  *
89  * This structure is used as a binary blob key for building and searching
90@@ -71,12 +79,13 @@ struct gl_shader_requirements
91 	bool input_is_premult:1;
92 	bool green_tint:1;
93 	unsigned color_pre_curve:1; /* enum gl_shader_color_curve */
94+	unsigned color_swap:2; /* enum gl_shader_color_swap */
95
96 	/*
97 	 * The total size of all bitfields plus pad_bits_ must fill up exactly
98 	 * how many bytes the compiler allocates for them together.
99 	 */
100-	unsigned pad_bits_:25;
101+	unsigned pad_bits_:23;
102 };
103 static_assert(sizeof(struct gl_shader_requirements) ==
104 	      4 /* total bitfield size in bytes */,
105diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c
106index c0863c1..33c1a8e 100644
107--- a/libweston/renderer-gl/gl-renderer.c
108+++ b/libweston/renderer-gl/gl-renderer.c
109@@ -193,6 +193,7 @@ struct gl_surface_state {
110 	struct egl_image* images[3];
111 	int num_images;
112 	enum gl_shader_texture_variant shader_variant;
113+	enum gl_shader_color_swap color_swap;
114
115 	struct weston_buffer_reference buffer_ref;
116 	struct weston_buffer_release_reference buffer_release_ref;
117@@ -1002,6 +1003,7 @@ gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
118 	int i;
119
120 	sconf->req.variant = gs->shader_variant;
121+	sconf->req.color_swap = gs->color_swap;
122 	sconf->req.input_is_premult =
123 		gl_shader_texture_variant_can_be_premult(gs->shader_variant);
124
125@@ -2097,6 +2099,67 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
126 		gl_pixel_type = GL_UNSIGNED_BYTE;
127 		es->is_opaque = false;
128 		break;
129+	case WL_SHM_FORMAT_XBGR8888:
130+		gs->shader_variant = SHADER_VARIANT_RGBX;
131+		pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
132+		gl_format[0] = GL_RGBA;
133+		gl_pixel_type = GL_UNSIGNED_BYTE;
134+		es->is_opaque = true;
135+		break;
136+	case WL_SHM_FORMAT_ABGR8888:
137+		gs->shader_variant = SHADER_VARIANT_RGBA;
138+		pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
139+		gl_format[0] = GL_RGBA;
140+		gl_pixel_type = GL_UNSIGNED_BYTE;
141+		es->is_opaque = false;
142+		break;
143+	case WL_SHM_FORMAT_RGBX8888:
144+		gs->shader_variant = SHADER_VARIANT_RGBX;
145+		gs->color_swap = SHADER_COLOR_SWAP_ALL;
146+		pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
147+		gl_format[0] = GL_RGBA;
148+		gl_pixel_type = GL_UNSIGNED_BYTE;
149+		es->is_opaque = true;
150+		break;
151+	case WL_SHM_FORMAT_RGBA8888:
152+		gs->shader_variant = SHADER_VARIANT_RGBA;
153+		gs->color_swap = SHADER_COLOR_SWAP_ALL;
154+		pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
155+		gl_format[0] = GL_RGBA;
156+		gl_pixel_type = GL_UNSIGNED_BYTE;
157+		es->is_opaque = false;
158+		break;
159+	case WL_SHM_FORMAT_BGRX8888:
160+		gs->shader_variant = SHADER_VARIANT_RGBX;
161+		gs->color_swap = SHADER_COLOR_SWAP_ALPHA;
162+		pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
163+		gl_format[0] = GL_RGBA;
164+		gl_pixel_type = GL_UNSIGNED_BYTE;
165+		es->is_opaque = true;
166+		break;
167+	case WL_SHM_FORMAT_BGRA8888:
168+		gs->shader_variant = SHADER_VARIANT_RGBA;
169+		gs->color_swap = SHADER_COLOR_SWAP_ALPHA;
170+		pitch = wl_shm_buffer_get_stride(shm_buffer) / 4;
171+		gl_format[0] = GL_RGBA;
172+		gl_pixel_type = GL_UNSIGNED_BYTE;
173+		es->is_opaque = false;
174+		break;
175+	case WL_SHM_FORMAT_RGB888:
176+		gs->shader_variant = SHADER_VARIANT_RGBX;
177+		pitch = wl_shm_buffer_get_stride(shm_buffer) / 3;
178+		gl_format[0] = GL_RGB;
179+		gl_pixel_type = GL_UNSIGNED_BYTE;
180+		es->is_opaque = true;
181+		break;
182+	case WL_SHM_FORMAT_BGR888:
183+		gs->shader_variant = SHADER_VARIANT_RGBX;
184+		gs->color_swap = SHADER_COLOR_SWAP_RGB;
185+		pitch = wl_shm_buffer_get_stride(shm_buffer) / 3;
186+		gl_format[0] = GL_RGB;
187+		gl_pixel_type = GL_UNSIGNED_BYTE;
188+		es->is_opaque = true;
189+		break;
190 	case WL_SHM_FORMAT_RGB565:
191 		gs->shader_variant = SHADER_VARIANT_RGBX;
192 		pitch = wl_shm_buffer_get_stride(shm_buffer) / 2;
193@@ -3924,6 +3987,14 @@ gl_renderer_display_create(struct weston_compositor *ec,
194 		goto fail_with_error;
195 	}
196
197+	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_XBGR8888);
198+	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_ABGR8888);
199+	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGBX8888);
200+	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGBA8888);
201+	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_BGRX8888);
202+	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_BGRA8888);
203+	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB888);
204+	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_BGR888);
205 	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB565);
206 	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_YUV420);
207 	wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_NV12);
208diff --git a/libweston/renderer-gl/gl-shaders.c b/libweston/renderer-gl/gl-shaders.c
209index 97f288c..6c515a6 100644
210--- a/libweston/renderer-gl/gl-shaders.c
211+++ b/libweston/renderer-gl/gl-shaders.c
212@@ -97,6 +97,21 @@ gl_shader_color_curve_to_string(enum gl_shader_color_curve kind)
213 	return "!?!?"; /* never reached */
214 }
215
216+static const char *
217+gl_shader_color_swap_to_string(enum gl_shader_color_swap kind)
218+{
219+	switch (kind) {
220+#define CASERET(x) case x: return #x;
221+	CASERET(SHADER_COLOR_SWAP_NONE)
222+	CASERET(SHADER_COLOR_SWAP_RGB)
223+	CASERET(SHADER_COLOR_SWAP_ALPHA)
224+	CASERET(SHADER_COLOR_SWAP_ALL)
225+#undef CASERET
226+	}
227+
228+	return "!?!?"; /* never reached */
229+}
230+
231 static void
232 dump_program_with_line_numbers(int count, const char **sources)
233 {
234@@ -182,10 +197,12 @@ create_shader_config_string(const struct gl_shader_requirements *req)
235 			"#define DEF_GREEN_TINT %s\n"
236 			"#define DEF_INPUT_IS_PREMULT %s\n"
237 			"#define DEF_COLOR_PRE_CURVE %s\n"
238+			"#define DEF_COLOR_SWAP %s\n"
239 			"#define DEF_VARIANT %s\n",
240 			req->green_tint ? "true" : "false",
241 			req->input_is_premult ? "true" : "false",
242 			gl_shader_color_curve_to_string(req->color_pre_curve),
243+			gl_shader_color_swap_to_string(req->color_swap),
244 			gl_shader_texture_variant_to_string(req->variant));
245 	if (size < 0)
246 		return NULL;
247--
2482.20.1
249
250