Bug 1845309 - Use highp for texcoords in DrawTargetWebgl shaders. r=jrmuizel

This issue was originally reported by Asahi Lina, and they also proposed the original
version of these changes. I have reworked them a bit just to clean up how clip TCs
are passed down so that distance AA does not have to be highp.

Their original comment describing the issue were, in part:

"See DrawTargetWebgl::SharedContext::CreateShaders in dom/canvas/DrawTargetWebgl.cpp. The fragment shaders specify precision mediump float; and then don't use overriding precision qualifiers anywhere. This causes the texcoords to use fp16 precision on GPUs that support it, which is not sufficient for correct rendering."

"Note that this is a common mistake and the Mesa GPU driver we've been developing actually includes a heuristic that fixes the first instance of the problem (where the varying is used as a texcoord directly), but not the second one where there is an intermediate clamp(). It is that second one that is breaking Google Sheets."

Differential Revision: https://phabricator.services.mozilla.com/D187694
This commit is contained in:
Lee Salzman
2023-09-07 18:10:24 +00:00
parent 068962bb83
commit db33f6ffeb

View File

@@ -1212,8 +1212,10 @@ bool DrawTargetWebgl::SharedContext::CreateShaders() {
u"attribute vec3 a_vertex;\n"
"uniform vec2 u_transform[3];\n"
"uniform vec2 u_viewport;\n"
"uniform vec4 u_clipbounds;\n"
"uniform float u_aa;\n"
"varying vec4 v_cliptc;\n"
"varying vec2 v_cliptc;\n"
"varying vec4 v_clipdist;\n"
"varying vec4 v_dist;\n"
"varying float v_alpha;\n"
"void main() {\n"
@@ -1227,7 +1229,9 @@ bool DrawTargetWebgl::SharedContext::CreateShaders() {
" u_transform[1] * extrude.y +\n"
" u_transform[2];\n"
" gl_Position = vec4(vertex * 2.0 / u_viewport - 1.0, 0.0, 1.0);\n"
" v_cliptc = vec4(vertex / u_viewport, vertex);\n"
" v_cliptc = vertex / u_viewport;\n"
" v_clipdist = vec4(vertex - u_clipbounds.xy,\n"
" u_clipbounds.zw - vertex);\n"
" v_dist = vec4(extrude, 1.0 - extrude) * scale.xyxy + 1.5 - u_aa;\n"
" v_alpha = a_vertex.z;\n"
"}\n"_ns;
@@ -1235,15 +1239,13 @@ bool DrawTargetWebgl::SharedContext::CreateShaders() {
u"precision mediump float;\n"
"uniform vec4 u_color;\n"
"uniform sampler2D u_clipmask;\n"
"uniform vec4 u_clipbounds;\n"
"varying vec4 v_cliptc;\n"
"varying highp vec2 v_cliptc;\n"
"varying vec4 v_clipdist;\n"
"varying vec4 v_dist;\n"
"varying float v_alpha;\n"
"void main() {\n"
" float clip = texture2D(u_clipmask, v_cliptc.xy).r;\n"
" vec4 clipdist = vec4(v_cliptc.zw - u_clipbounds.xy,\n"
" u_clipbounds.zw - v_cliptc.zw);\n"
" vec4 dist = min(v_dist, clipdist);\n"
" float clip = texture2D(u_clipmask, v_cliptc).r;\n"
" vec4 dist = min(v_dist, v_clipdist);\n"
" dist.xy = min(dist.xy, dist.zw);\n"
" float aa = v_alpha * clamp(min(dist.x, dist.y), 0.0, 1.0);\n"
" gl_FragColor = clip * aa * u_color;\n"
@@ -1294,11 +1296,13 @@ bool DrawTargetWebgl::SharedContext::CreateShaders() {
auto vsSource =
u"attribute vec3 a_vertex;\n"
"uniform vec2 u_viewport;\n"
"uniform vec4 u_clipbounds;\n"
"uniform float u_aa;\n"
"uniform vec2 u_transform[3];\n"
"uniform vec2 u_texmatrix[3];\n"
"varying vec4 v_cliptc;\n"
"varying vec2 v_cliptc;\n"
"varying vec2 v_texcoord;\n"
"varying vec4 v_clipdist;\n"
"varying vec4 v_dist;\n"
"varying float v_alpha;\n"
"void main() {\n"
@@ -1312,7 +1316,9 @@ bool DrawTargetWebgl::SharedContext::CreateShaders() {
" u_transform[1] * extrude.y +\n"
" u_transform[2];\n"
" gl_Position = vec4(vertex * 2.0 / u_viewport - 1.0, 0.0, 1.0);\n"
" v_cliptc = vec4(vertex / u_viewport, vertex);\n"
" v_cliptc = vertex / u_viewport;\n"
" v_clipdist = vec4(vertex - u_clipbounds.xy,\n"
" u_clipbounds.zw - vertex);\n"
" v_texcoord = u_texmatrix[0] * extrude.x +\n"
" u_texmatrix[1] * extrude.y +\n"
" u_texmatrix[2];\n"
@@ -1326,18 +1332,17 @@ bool DrawTargetWebgl::SharedContext::CreateShaders() {
"uniform float u_swizzle;\n"
"uniform sampler2D u_sampler;\n"
"uniform sampler2D u_clipmask;\n"
"uniform vec4 u_clipbounds;\n"
"varying vec4 v_cliptc;\n"
"varying vec2 v_texcoord;\n"
"varying highp vec2 v_cliptc;\n"
"varying highp vec2 v_texcoord;\n"
"varying vec4 v_clipdist;\n"
"varying vec4 v_dist;\n"
"varying float v_alpha;\n"
"void main() {\n"
" vec2 tc = clamp(v_texcoord, u_texbounds.xy, u_texbounds.zw);\n"
" highp vec2 tc = clamp(v_texcoord, u_texbounds.xy,\n"
" u_texbounds.zw);\n"
" vec4 image = texture2D(u_sampler, tc);\n"
" float clip = texture2D(u_clipmask, v_cliptc.xy).r;\n"
" vec4 clipdist = vec4(v_cliptc.zw - u_clipbounds.xy,\n"
" u_clipbounds.zw - v_cliptc.zw);\n"
" vec4 dist = min(v_dist, clipdist);\n"
" float clip = texture2D(u_clipmask, v_cliptc).r;\n"
" vec4 dist = min(v_dist, v_clipdist);\n"
" dist.xy = min(dist.xy, dist.zw);\n"
" float aa = v_alpha * clamp(min(dist.x, dist.y), 0.0, 1.0);\n"
" gl_FragColor = clip * aa * u_color *\n"