gecko-dev/gfx/wr/webrender/res/cs_gradient.glsl
Glenn Watson e920cc3f6a Bug 1533236 - Add a fast path to WR for common gradient types. r=kvark
The existing linear gradient shader is quite slow, especially
on very large gradients on integrated GPUs.

The vast majority of gradients in real content are very simple
(typically < 4 stops, no angle, no repeat). For these, we can
run a fast path to persist a small gradient in the texture cache
and draw the gradient via the image shader.

This is _much_ faster than the catch-all gradient shader, and also
results in better batching while drawing the main scene.

In future, we can expand the fast path to handle more cases, such
as angled gradients. For now, it takes a conservative approach,
but still seems to hit the fast path on most real content.

Differential Revision: https://phabricator.services.mozilla.com/D22445

--HG--
extra : moz-landing-system : lando
2019-03-07 21:20:40 +00:00

57 lines
1.3 KiB
GLSL

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include shared
varying float vPos;
flat varying vec4 vStops;
flat varying vec4 vColor0;
flat varying vec4 vColor1;
flat varying vec4 vColor2;
flat varying vec4 vColor3;
#ifdef WR_VERTEX_SHADER
in vec4 aTaskRect;
in float aAxisSelect;
in vec4 aStops;
in vec4 aColor0;
in vec4 aColor1;
in vec4 aColor2;
in vec4 aColor3;
in vec2 aStartStop;
void main(void) {
vPos = mix(aStartStop.x, aStartStop.y, mix(aPosition.x, aPosition.y, aAxisSelect));
vStops = aStops;
vColor0 = aColor0;
vColor1 = aColor1;
vColor2 = aColor2;
vColor3 = aColor3;
gl_Position = uTransform * vec4(aTaskRect.xy + aTaskRect.zw * aPosition.xy, 0.0, 1.0);
}
#endif
#ifdef WR_FRAGMENT_SHADER
float linear_step(float edge0, float edge1, float x) {
if (edge0 >= edge1) {
return 0.0;
}
return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
}
void main(void) {
vec4 color = vColor0;
color = mix(color, vColor1, linear_step(vStops.x, vStops.y, vPos));
color = mix(color, vColor2, linear_step(vStops.y, vStops.z, vPos));
color = mix(color, vColor3, linear_step(vStops.z, vStops.w, vPos));
oFragColor = color;
}
#endif