| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <impeller/texture.glsl> |
| #include <impeller/types.glsl> |
| |
| // Unused, see See PointFieldGeometry::GetPositionBuffer |
| layout(local_size_x = 16) in; |
| |
| layout(std430) readonly buffer GeometryData { |
| // Size of this input data is frame_info.count; |
| vec2 points[]; |
| } |
| geometry_data; |
| |
| layout(std430) writeonly buffer GeometryUVData { |
| // Size of this output data is frame_info.count; |
| // x,y is the original geometry. |
| // u,v is the texture UV. |
| vec4 points_uv[]; |
| } |
| geometry_uv_data; |
| |
| uniform FrameInfo { |
| uint count; |
| mat4 effect_transform; |
| vec2 texture_origin; |
| vec2 texture_size; |
| } |
| frame_info; |
| |
| vec2 project_point(mat4 m, vec2 v) { |
| float w = v.x * m[0][3] + v.y * m[1][3] + m[3][3]; |
| vec2 result = vec2(v.x * m[0][0] + v.y * m[1][0] + m[3][0], |
| v.x * m[0][1] + v.y * m[1][1] + m[3][1]); |
| |
| // This is Skia's behavior, but it may be reasonable to allow UB for the w=0 |
| // case. |
| if (w != 0) { |
| w = 1 / w; |
| } |
| return result * w; |
| } |
| |
| void main() { |
| uint ident = gl_GlobalInvocationID.x; |
| if (ident >= frame_info.count) { |
| return; |
| } |
| |
| vec2 point = geometry_data.points[ident]; |
| |
| vec2 coverage_coords = |
| (point - frame_info.texture_origin) / frame_info.texture_size; |
| vec2 texture_coords = |
| project_point(frame_info.effect_transform, coverage_coords); |
| |
| geometry_uv_data.points_uv[ident] = vec4(point, texture_coords); |
| } |