Various shaders broken on i.MX 8
- which version of GTK are you using? 4.11.1
- which operating system are you using? NXP i.MX8 Toradex OpenEmbedded image (tdx-xwayland Reference Multimedia Image 6.2.0)
- what display and graphics driver are you using?
Wayland Display server (1.22.0)
OpenGL Information
GL_VENDOR: Vivante Corporation
GL_RENDERER: Vivante GC7000L
GL_VERSION: OpenGL ES 3.1 V6.4.3.p4.398061
-
the necessary steps to reproduce the issue
Execute gtk4-demo. Observe the gradient in the buttons being broken, as well as the checkboxes.
-
the expected outcome
The widgets rendering properly
-
a description of the behavior; screenshots are also welcome
Apparently a division through 0 happens in the gradient shader. (current_offset and next_offset apparently equal to 0 at some point in the last for loop leading to this behavior)
This leads to the gradient (and other elements) only being partially drawn. Likely a similar problem occurs when drawing checkboxes.
Applying the following patch allows for the buttons to be drawn as expected, while the checkboxes are still not rendering correctly:
diff --git a/gsk/gl/resources/conic_gradient.glsl b/gsk/gl/resources/conic_gradient.glsl
index f1d33cd..4c5e54c 100644
--- a/gsk/gl/resources/conic_gradient.glsl
+++ b/gsk/gl/resources/conic_gradient.glsl
@@ -73,6 +73,12 @@ void main() {
curr_offset = next_offset;
next_offset = get_offset(i + 1);
+ if (next_offset <= curr_offset) {
+ vec4 curr_color = gsk_premultiply(get_color(i));
+ gskSetScaledOutputColor(curr_color, u_alpha);
+ return;
+ }
+
if (offset < next_offset) {
float f = (offset - curr_offset) / (next_offset - curr_offset);
vec4 curr_color = gsk_premultiply(get_color(i));
diff --git a/gsk/gl/resources/linear_gradient.glsl b/gsk/gl/resources/linear_gradient.glsl
index fa130be..979c643 100644
--- a/gsk/gl/resources/linear_gradient.glsl
+++ b/gsk/gl/resources/linear_gradient.glsl
@@ -95,6 +95,12 @@ void main() {
curr_offset = next_offset;
next_offset = get_offset(i + 1);
+ if (next_offset <= curr_offset) {
+ vec4 curr_color = gsk_premultiply(get_color(i));
+ gskSetScaledOutputColor(curr_color, u_alpha);
+ return;
+ }
+
if (offset < next_offset) {
float f = (offset - curr_offset) / (next_offset - curr_offset);
vec4 curr_color = gsk_premultiply(get_color(i));
diff --git a/gsk/gl/resources/radial_gradient.glsl b/gsk/gl/resources/radial_gradient.glsl
index 59fad00..f99eb0d 100644
--- a/gsk/gl/resources/radial_gradient.glsl
+++ b/gsk/gl/resources/radial_gradient.glsl
@@ -75,6 +75,12 @@ void main() {
curr_offset = next_offset;
next_offset = get_offset(i + 1);
+ if (next_offset <= curr_offset) {
+ vec4 curr_color = gsk_premultiply(get_color(i));
+ gskSetScaledOutputColor(curr_color, u_alpha);
+ return;
+ }
+
if (offset < next_offset) {
float f = (offset - curr_offset) / (next_offset - curr_offset);
vec4 curr_color = gsk_premultiply(get_color(i));
EDIT: Apparently the shader used for the check boxes is actually the same, meaning my patch is flawed and still doesn't fix everything.