2017-02-06 19:42:52 +03:00
|
|
|
/* 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/. */
|
|
|
|
|
2018-04-09 15:26:07 +03:00
|
|
|
#include shared,clip_shared
|
2017-08-24 17:27:22 +03:00
|
|
|
|
2017-02-06 19:42:52 +03:00
|
|
|
varying vec3 vPos;
|
2018-04-09 15:26:07 +03:00
|
|
|
varying vec3 vClipMaskImageUv;
|
|
|
|
|
2017-02-06 19:42:52 +03:00
|
|
|
flat varying vec4 vClipMaskUvRect;
|
2017-02-16 22:45:41 +03:00
|
|
|
flat varying vec4 vClipMaskUvInnerRect;
|
2017-08-18 15:51:39 +03:00
|
|
|
flat varying float vLayer;
|
2017-09-19 19:11:59 +03:00
|
|
|
|
|
|
|
#ifdef WR_VERTEX_SHADER
|
|
|
|
struct ImageMaskData {
|
|
|
|
RectWithSize local_rect;
|
|
|
|
};
|
|
|
|
|
|
|
|
ImageMaskData fetch_mask_data(ivec2 address) {
|
|
|
|
vec4 data = fetch_from_resource_cache_1_direct(address);
|
2017-10-31 16:08:43 +03:00
|
|
|
RectWithSize local_rect = RectWithSize(data.xy, data.zw);
|
|
|
|
ImageMaskData mask_data = ImageMaskData(local_rect);
|
|
|
|
return mask_data;
|
2017-09-19 19:11:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void main(void) {
|
|
|
|
ClipMaskInstance cmi = fetch_clip_item();
|
|
|
|
ClipArea area = fetch_clip_area(cmi.render_task_address);
|
2018-01-08 17:19:23 +03:00
|
|
|
ClipScrollNode scroll_node = fetch_clip_scroll_node(cmi.scroll_node_id);
|
2017-09-19 19:11:59 +03:00
|
|
|
ImageMaskData mask = fetch_mask_data(cmi.clip_data_address);
|
|
|
|
RectWithSize local_rect = mask.local_rect;
|
|
|
|
ImageResource res = fetch_image_resource_direct(cmi.resource_address);
|
|
|
|
|
|
|
|
ClipVertexInfo vi = write_clip_tile_vertex(local_rect,
|
2018-01-08 17:19:23 +03:00
|
|
|
scroll_node,
|
2017-12-05 19:51:33 +03:00
|
|
|
area);
|
2017-09-19 19:11:59 +03:00
|
|
|
|
|
|
|
vPos = vi.local_pos;
|
|
|
|
vLayer = res.layer;
|
|
|
|
|
2018-04-09 15:26:07 +03:00
|
|
|
vClipMaskImageUv = vec3((vPos.xy / vPos.z - local_rect.p0) / local_rect.size, 0.0);
|
2017-09-19 19:11:59 +03:00
|
|
|
vec2 texture_size = vec2(textureSize(sColor0, 0));
|
2018-01-24 17:13:07 +03:00
|
|
|
vClipMaskUvRect = vec4(res.uv_rect.p0, res.uv_rect.p1 - res.uv_rect.p0) / texture_size.xyxy;
|
2017-09-19 19:11:59 +03:00
|
|
|
// applying a half-texel offset to the UV boundaries to prevent linear samples from the outside
|
2018-01-24 17:13:07 +03:00
|
|
|
vec4 inner_rect = vec4(res.uv_rect.p0, res.uv_rect.p1);
|
2017-09-19 19:11:59 +03:00
|
|
|
vClipMaskUvInnerRect = (inner_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef WR_FRAGMENT_SHADER
|
|
|
|
void main(void) {
|
2017-11-23 17:38:38 +03:00
|
|
|
float alpha = init_transform_fs(vPos.xy / vPos.z);
|
2017-09-19 19:11:59 +03:00
|
|
|
|
|
|
|
bool repeat_mask = false; //TODO
|
2018-04-09 15:26:07 +03:00
|
|
|
vec2 clamped_mask_uv = repeat_mask ? fract(vClipMaskImageUv.xy) :
|
|
|
|
clamp(vClipMaskImageUv.xy, vec2(0.0, 0.0), vec2(1.0, 1.0));
|
2017-09-19 19:11:59 +03:00
|
|
|
vec2 source_uv = clamp(clamped_mask_uv * vClipMaskUvRect.zw + vClipMaskUvRect.xy,
|
|
|
|
vClipMaskUvInnerRect.xy, vClipMaskUvInnerRect.zw);
|
|
|
|
float clip_alpha = texture(sColor0, vec3(source_uv, vLayer)).r; //careful: texture has type A8
|
|
|
|
|
2017-10-27 15:51:39 +03:00
|
|
|
oFragColor = vec4(alpha * clip_alpha, 1.0, 1.0, 1.0);
|
2017-09-19 19:11:59 +03:00
|
|
|
}
|
|
|
|
#endif
|