зеркало из https://github.com/mozilla/gecko-dev.git
142 строки
4.6 KiB
GLSL
142 строки
4.6 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/. */
|
|
|
|
#define VECS_PER_SPECIFIC_BRUSH 0
|
|
|
|
#include shared,prim_shared,brush
|
|
|
|
#ifdef WR_FEATURE_ALPHA_PASS
|
|
varying vec2 vLocalPos;
|
|
#endif
|
|
|
|
varying vec3 vUv;
|
|
flat varying int vImageKind;
|
|
flat varying vec4 vUvBounds;
|
|
flat varying vec4 vUvBounds_NoClamp;
|
|
flat varying vec4 vParams;
|
|
|
|
#if defined WR_FEATURE_ALPHA_TARGET || defined WR_FEATURE_COLOR_TARGET_ALPHA_MASK
|
|
flat varying vec4 vColor;
|
|
#endif
|
|
|
|
#define BRUSH_IMAGE_SIMPLE 0
|
|
#define BRUSH_IMAGE_NINEPATCH 1
|
|
#define BRUSH_IMAGE_MIRROR 2
|
|
|
|
#ifdef WR_VERTEX_SHADER
|
|
void brush_vs(
|
|
int prim_address,
|
|
vec2 local_pos,
|
|
RectWithSize local_rect,
|
|
ivec2 user_data,
|
|
PictureTask pic_task
|
|
) {
|
|
// TODO(gw): For now, this brush_image shader is only
|
|
// being used to draw items from the intermediate
|
|
// surface cache (render tasks). In the future
|
|
// we can expand this to support items from
|
|
// the normal texture cache and unify this
|
|
// with the normal image shader.
|
|
BlurTask blur_task = fetch_blur_task(user_data.x);
|
|
vUv.z = blur_task.common_data.texture_layer_index;
|
|
vImageKind = user_data.y;
|
|
|
|
#if defined WR_FEATURE_COLOR_TARGET
|
|
vec2 texture_size = vec2(textureSize(sColor0, 0).xy);
|
|
#elif defined WR_FEATURE_COLOR_TARGET_ALPHA_MASK
|
|
vec2 texture_size = vec2(textureSize(sColor0, 0).xy);
|
|
vColor = blur_task.color;
|
|
#else
|
|
vec2 texture_size = vec2(textureSize(sColor1, 0).xy);
|
|
vColor = blur_task.color;
|
|
#endif
|
|
|
|
vec2 uv0 = blur_task.common_data.task_rect.p0;
|
|
vec2 src_size = blur_task.common_data.task_rect.size * blur_task.scale_factor;
|
|
vec2 uv1 = uv0 + blur_task.common_data.task_rect.size;
|
|
|
|
// TODO(gw): In the future we'll probably draw these as segments
|
|
// with the brush shader. When that occurs, we can
|
|
// modify the UVs for each segment in the VS, and the
|
|
// FS can become a simple shader that doesn't need
|
|
// to adjust the UVs.
|
|
|
|
switch (vImageKind) {
|
|
case BRUSH_IMAGE_SIMPLE: {
|
|
vec2 f = (local_pos - local_rect.p0) / local_rect.size;
|
|
vUv.xy = mix(uv0, uv1, f);
|
|
vUv.xy /= texture_size;
|
|
break;
|
|
}
|
|
case BRUSH_IMAGE_NINEPATCH: {
|
|
vec2 local_src_size = src_size / uDevicePixelRatio;
|
|
vUv.xy = (local_pos - local_rect.p0) / local_src_size;
|
|
vParams.xy = vec2(0.5);
|
|
vParams.zw = (local_rect.size / local_src_size - 0.5);
|
|
break;
|
|
}
|
|
case BRUSH_IMAGE_MIRROR: {
|
|
vec2 local_src_size = src_size / uDevicePixelRatio;
|
|
vUv.xy = (local_pos - local_rect.p0) / local_src_size;
|
|
vParams.xy = 0.5 * local_rect.size / local_src_size;
|
|
break;
|
|
}
|
|
}
|
|
|
|
vUvBounds = vec4(uv0 + vec2(0.5), uv1 - vec2(0.5)) / texture_size.xyxy;
|
|
vUvBounds_NoClamp = vec4(uv0, uv1) / texture_size.xyxy;
|
|
|
|
#ifdef WR_FEATURE_ALPHA_PASS
|
|
vLocalPos = local_pos;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef WR_FRAGMENT_SHADER
|
|
vec4 brush_fs() {
|
|
vec2 uv;
|
|
|
|
switch (vImageKind) {
|
|
case BRUSH_IMAGE_SIMPLE: {
|
|
uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw);
|
|
break;
|
|
}
|
|
case BRUSH_IMAGE_NINEPATCH: {
|
|
uv = clamp(vUv.xy, vec2(0.0), vParams.xy);
|
|
uv += max(vec2(0.0), vUv.xy - vParams.zw);
|
|
uv = mix(vUvBounds_NoClamp.xy, vUvBounds_NoClamp.zw, uv);
|
|
uv = clamp(uv, vUvBounds.xy, vUvBounds.zw);
|
|
break;
|
|
}
|
|
case BRUSH_IMAGE_MIRROR: {
|
|
// Mirror and stretch the box shadow corner over the entire
|
|
// primitives.
|
|
uv = vParams.xy - abs(vUv.xy - vParams.xy);
|
|
|
|
// Ensure that we don't fetch texels outside the box
|
|
// shadow corner. This can happen, for example, when
|
|
// drawing the outer parts of an inset box shadow.
|
|
uv = clamp(uv, vec2(0.0), vec2(1.0));
|
|
uv = mix(vUvBounds_NoClamp.xy, vUvBounds_NoClamp.zw, uv);
|
|
uv = clamp(uv, vUvBounds.xy, vUvBounds.zw);
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if defined WR_FEATURE_COLOR_TARGET
|
|
vec4 color = texture(sColor0, vec3(uv, vUv.z));
|
|
#elif defined WR_FEATURE_COLOR_TARGET_ALPHA_MASK
|
|
vec4 color = vColor * texture(sColor0, vec3(uv, vUv.z)).a;
|
|
#else
|
|
vec4 color = vColor * texture(sColor1, vec3(uv, vUv.z)).r;
|
|
#endif
|
|
|
|
#ifdef WR_FEATURE_ALPHA_PASS
|
|
color *= init_transform_fs(vLocalPos);
|
|
#endif
|
|
|
|
return color;
|
|
}
|
|
#endif
|