Incorrect drawing image with wayland on Mali400

Symptom

I found there have some display problem when enable fade in or out. (if i disable fade animation, problem occurs when surface destroyed only)

The display error area is on the right-up corner.

Original image Error image

 

I already know that Mali 4xx series have the h/w limitation. The limitation is, the floating point is implemented in 16-bit in fragment shader of Mali 4xx. So there could be issues when precision requirement is high.

But I think it is strange that the triangle pattern appears just like the above because of the high precision.

How to reproduce

1) To reproduce this error more easier, I modify some part of weston code. you can check below patch.

diff --git a/clients/image.c b/clients/image.c
index 4126305..7955d24 100644
--- a/clients/image.c
+++ b/clients/image.c
@@ -380,6 +380,7 @@ image_create(struct display *display, const char *filename,
 	}
 
 	image->window = window_create(display);
+    //window_set_fullscreen(image->window, 1);
 	image->widget = window_frame_create(image->window, image);
 	window_set_title(image->window, title);
 	image->display = display;
@@ -400,7 +401,7 @@ image_create(struct display *display, const char *filename,
 	widget_set_button_handler(image->widget, button_handler);
 	widget_set_axis_handler(image->widget, axis_handler);
 	window_set_key_handler(image->window, key_handler);
-	widget_schedule_resize(image->widget, 500, 400);
+	widget_schedule_resize(image->widget, 1024, 600);
 
 	return image;
 }
diff --git a/clients/window.c b/clients/window.c
index 0e73f5b..2f0e36f 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -2155,7 +2155,7 @@ frame_resize_handler(struct widget *widget,
 	struct rectangle input;
 	struct rectangle opaque;
 
-	if (widget->window->fullscreen) {
+	if (1){//widget->window->fullscreen) {
 		interior.x = 0;
 		interior.y = 0;
 		interior.width = width;

 

2) You have to enable fade animation in your weston.ini file.

weston.ini

panel-location=none
locking=true
animation=fade

...

My debugging note

  • Ubuntu (weston 1.11.1) Does it work in a desktop environment? => Yes, it is normal.
  • Drawing problems occurred under the condition of "1 pixel wide black and white vertical line"
  • The currently tested wayland version is 1.9.0, is it the same in version 1.12.0? => Regardless of version.

If i disable the weston_matrix_init() function in weston_view_animation_create() function, error seems like disappeared.

So I suspected that there would be a problem with weston's animation algorithm. But as a result of searching at wayland bugreport, no user has ever reported an error related this issue.

Questions

  1. What i really want to know is, 'Why does the GPU draw a triangle on the top right corner?'
  2. Is there another way to avoid precision error?
  3. I think i can avoid precision error if i know the exact root cause. It's a difficult process, but somebody help me?

 

  • What i really want to know is, 'Why does the GPU draw a triangle on the top right corner?'

    I assume the UI rendering is drawing the screen as two triangles, each covering the screen with the split running from-top right to bottom-left. The corner of the triangle has the highest value range, so needs higher precision for sub-texel sample precision.

    Is there another way to avoid precision error?

    Mali-400 only supports mediump (fp16) precision in fragment shader arithmetic units, as you already noted, so if this is your problem then there is no easy fix.

    If the issue is texture coordinate precision note that if you use a varying directly as a texture coordinate, with no computation on the varying value, then there is a higher precision path which should avoid sample coordinate related artifacts. If you do any maths on the varying first then it will be forced to fp16 and the additional precision will be lost.

    I'm pretty sure the issue is that your texture coordinates are being converted to fp16 because arithmetic is being performed on them before they are used. For fp16 values above the 0.5 limit on the texture coordinate the fp16 "increment" between values is 2^-11, or about 0.000488. For a texture which is 1024 pixels wide this give an sample point accuracy of only +- half a pixel width which is insufficient for accurate sampling (especially when using GL_LINEAR filtering).

    Short answer: don't do maths on texture coordinates in the fragment shader.

    HTH, 
    Pete

  • Thank you for your help.

    I got some answers from the wayland development mail based on your analysis.

    Short answer: don't do maths on texture coordinates in the fragment shader.

    Weston does not do math with texcoords in the fragment shaders, it just uses the interpolated coordinates from the vertex shader directly. The vertex shared does not compute with the texcoords either.

    The maintainer of the wayland development said,

    If you're worried about FP16 interpolation accuracy (which, as the vendor states, only gets you 10 bits of accuracy, so only 1024 different values -- definitely not big enough to drive a maximized window at normal desktop resolutions), you can try using normalized GL_SHORT texture coordinates instead. I don't know if the hardware you have supports fixed-point interpolation for vertex attributes, you would need to ask your vendor about that.

    I tried to check if the Mali GPU supports fixed-point interpolation on the ARM application development guide, but I could not find it.

    I would appreciate your help.

    Regards,

    YoungJun

  • try using normalized GL_SHORT texture coordinates instead

    Shouldn't make any difference - as long as your texture coordinates into the shader are fp32 (highp) and there is no maths in the fragment shader on the coordinate you should have enough precision.