| File: | root/firefox-clang/obj-x86_64-pc-linux-gnu/x86_64-unknown-linux-gnu/debug/build/swgl-1f454ffad5667e37/out/cs_path_tile.h |
| Warning: | line 233, column 14 Value stored to 'texel1' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | struct cs_path_tile_common { |
| 2 | struct Samplers { |
| 3 | sampler2D_impl sGpuBufferF_impl; |
| 4 | int sGpuBufferF_slot; |
| 5 | isampler2D_impl sGpuBufferI_impl; |
| 6 | int sGpuBufferI_slot; |
| 7 | sampler2D_impl sPathEdges_impl; |
| 8 | int sPathEdges_slot; |
| 9 | sampler2D_impl sRenderTasks_impl; |
| 10 | int sRenderTasks_slot; |
| 11 | bool set_slot(int index, int value) { |
| 12 | switch (index) { |
| 13 | case 2: |
| 14 | sGpuBufferF_slot = value; |
| 15 | return true; |
| 16 | case 3: |
| 17 | sGpuBufferI_slot = value; |
| 18 | return true; |
| 19 | case 5: |
| 20 | sPathEdges_slot = value; |
| 21 | return true; |
| 22 | case 1: |
| 23 | sRenderTasks_slot = value; |
| 24 | return true; |
| 25 | } |
| 26 | return false; |
| 27 | } |
| 28 | } samplers; |
| 29 | struct AttribLocations { |
| 30 | int aPosition = NULL_ATTRIB16; |
| 31 | int aData = NULL_ATTRIB16; |
| 32 | void bind_loc(const char* name, int index) { |
| 33 | if (strcmp("aPosition", name) == 0) { aPosition = index; return; } |
| 34 | if (strcmp("aData", name) == 0) { aData = index; return; } |
| 35 | } |
| 36 | int get_loc(const char* name) const { |
| 37 | if (strcmp("aPosition", name) == 0) { return aPosition != NULL_ATTRIB16 ? aPosition : -1; } |
| 38 | if (strcmp("aData", name) == 0) { return aData != NULL_ATTRIB16 ? aData : -1; } |
| 39 | return -1; |
| 40 | } |
| 41 | } attrib_locations; |
| 42 | ivec4_scalar vTileData; |
| 43 | sampler2D sGpuBufferF; |
| 44 | isampler2D sGpuBufferI; |
| 45 | sampler2D sPathEdges; |
| 46 | sampler2D sRenderTasks; |
| 47 | mat4_scalar uTransform; |
| 48 | void bind_textures() { |
| 49 | sGpuBufferF = lookup_sampler(&samplers.sGpuBufferF_impl, samplers.sGpuBufferF_slot); |
| 50 | sGpuBufferI = lookup_isampler(&samplers.sGpuBufferI_impl, samplers.sGpuBufferI_slot); |
| 51 | sPathEdges = lookup_sampler(&samplers.sPathEdges_impl, samplers.sPathEdges_slot); |
| 52 | sRenderTasks = lookup_sampler(&samplers.sRenderTasks_impl, samplers.sRenderTasks_slot); |
| 53 | } |
| 54 | }; |
| 55 | struct cs_path_tile_vert : VertexShaderImpl, cs_path_tile_common { |
| 56 | private: |
| 57 | typedef cs_path_tile_vert Self; |
| 58 | // mat4_scalar uTransform; |
| 59 | vec2 aPosition; |
| 60 | struct RectWithSize_scalar { |
| 61 | vec2_scalar p0; |
| 62 | vec2_scalar size; |
| 63 | RectWithSize_scalar() = default; |
| 64 | RectWithSize_scalar(vec2_scalar p0, vec2_scalar size) : p0(p0), size(size){} |
| 65 | }; |
| 66 | struct RectWithSize { |
| 67 | vec2 p0; |
| 68 | vec2 size; |
| 69 | RectWithSize() = default; |
| 70 | RectWithSize(vec2 p0, vec2 size) : p0(p0), size(size){} |
| 71 | RectWithSize(vec2_scalar p0, vec2_scalar size):p0(p0),size(size){ |
| 72 | } |
| 73 | IMPLICIT RectWithSize(RectWithSize_scalar s):p0(s.p0),size(s.size){ |
| 74 | } |
| 75 | friend RectWithSize if_then_else(I32 c, RectWithSize t, RectWithSize e) { return RectWithSize( |
| 76 | if_then_else(c, t.p0, e.p0), if_then_else(c, t.size, e.size)); |
| 77 | }}; |
| 78 | struct RectWithEndpoint_scalar { |
| 79 | vec2_scalar p0; |
| 80 | vec2_scalar p1; |
| 81 | RectWithEndpoint_scalar() = default; |
| 82 | RectWithEndpoint_scalar(vec2_scalar p0, vec2_scalar p1) : p0(p0), p1(p1){} |
| 83 | }; |
| 84 | struct RectWithEndpoint { |
| 85 | vec2 p0; |
| 86 | vec2 p1; |
| 87 | RectWithEndpoint() = default; |
| 88 | RectWithEndpoint(vec2 p0, vec2 p1) : p0(p0), p1(p1){} |
| 89 | RectWithEndpoint(vec2_scalar p0, vec2_scalar p1):p0(p0),p1(p1){ |
| 90 | } |
| 91 | IMPLICIT RectWithEndpoint(RectWithEndpoint_scalar s):p0(s.p0),p1(s.p1){ |
| 92 | } |
| 93 | friend RectWithEndpoint if_then_else(I32 c, RectWithEndpoint t, RectWithEndpoint e) { return RectWithEndpoint( |
| 94 | if_then_else(c, t.p0, e.p0), if_then_else(c, t.p1, e.p1)); |
| 95 | }}; |
| 96 | // sampler2D sRenderTasks; |
| 97 | struct RenderTaskData_scalar { |
| 98 | RectWithEndpoint_scalar task_rect; |
| 99 | vec4_scalar user_data; |
| 100 | RenderTaskData_scalar() = default; |
| 101 | RenderTaskData_scalar(RectWithEndpoint_scalar task_rect, vec4_scalar user_data) : task_rect(task_rect), user_data(user_data){} |
| 102 | }; |
| 103 | struct RenderTaskData { |
| 104 | RectWithEndpoint task_rect; |
| 105 | vec4 user_data; |
| 106 | RenderTaskData() = default; |
| 107 | RenderTaskData(RectWithEndpoint task_rect, vec4 user_data) : task_rect(task_rect), user_data(user_data){} |
| 108 | RenderTaskData(RectWithEndpoint_scalar task_rect, vec4_scalar user_data):task_rect(task_rect),user_data(user_data){ |
| 109 | } |
| 110 | IMPLICIT RenderTaskData(RenderTaskData_scalar s):task_rect(s.task_rect),user_data(s.user_data){ |
| 111 | } |
| 112 | friend RenderTaskData if_then_else(I32 c, RenderTaskData t, RenderTaskData e) { return RenderTaskData( |
| 113 | if_then_else(c, t.task_rect, e.task_rect), if_then_else(c, t.user_data, e.user_data)); |
| 114 | }}; |
| 115 | struct PictureTask_scalar { |
| 116 | RectWithEndpoint_scalar task_rect; |
| 117 | float device_pixel_scale; |
| 118 | vec2_scalar content_origin; |
| 119 | PictureTask_scalar() = default; |
| 120 | PictureTask_scalar(RectWithEndpoint_scalar task_rect, float device_pixel_scale, vec2_scalar content_origin) : task_rect(task_rect), device_pixel_scale(device_pixel_scale), content_origin(content_origin){} |
| 121 | }; |
| 122 | struct PictureTask { |
| 123 | RectWithEndpoint task_rect; |
| 124 | Float device_pixel_scale; |
| 125 | vec2 content_origin; |
| 126 | PictureTask() = default; |
| 127 | PictureTask(RectWithEndpoint task_rect, Float device_pixel_scale, vec2 content_origin) : task_rect(task_rect), device_pixel_scale(device_pixel_scale), content_origin(content_origin){} |
| 128 | PictureTask(RectWithEndpoint_scalar task_rect, float device_pixel_scale, vec2_scalar content_origin):task_rect(task_rect),device_pixel_scale(device_pixel_scale),content_origin(content_origin){ |
| 129 | } |
| 130 | IMPLICIT PictureTask(PictureTask_scalar s):task_rect(s.task_rect),device_pixel_scale(s.device_pixel_scale),content_origin(s.content_origin){ |
| 131 | } |
| 132 | friend PictureTask if_then_else(I32 c, PictureTask t, PictureTask e) { return PictureTask( |
| 133 | if_then_else(c, t.task_rect, e.task_rect), if_then_else(c, t.device_pixel_scale, e.device_pixel_scale), if_then_else(c, t.content_origin, e.content_origin)); |
| 134 | }}; |
| 135 | struct ClipArea_scalar { |
| 136 | RectWithEndpoint_scalar task_rect; |
| 137 | float device_pixel_scale; |
| 138 | vec2_scalar screen_origin; |
| 139 | ClipArea_scalar() = default; |
| 140 | ClipArea_scalar(RectWithEndpoint_scalar task_rect, float device_pixel_scale, vec2_scalar screen_origin) : task_rect(task_rect), device_pixel_scale(device_pixel_scale), screen_origin(screen_origin){} |
| 141 | }; |
| 142 | struct ClipArea { |
| 143 | RectWithEndpoint task_rect; |
| 144 | Float device_pixel_scale; |
| 145 | vec2 screen_origin; |
| 146 | ClipArea() = default; |
| 147 | ClipArea(RectWithEndpoint task_rect, Float device_pixel_scale, vec2 screen_origin) : task_rect(task_rect), device_pixel_scale(device_pixel_scale), screen_origin(screen_origin){} |
| 148 | ClipArea(RectWithEndpoint_scalar task_rect, float device_pixel_scale, vec2_scalar screen_origin):task_rect(task_rect),device_pixel_scale(device_pixel_scale),screen_origin(screen_origin){ |
| 149 | } |
| 150 | IMPLICIT ClipArea(ClipArea_scalar s):task_rect(s.task_rect),device_pixel_scale(s.device_pixel_scale),screen_origin(s.screen_origin){ |
| 151 | } |
| 152 | friend ClipArea if_then_else(I32 c, ClipArea t, ClipArea e) { return ClipArea( |
| 153 | if_then_else(c, t.task_rect, e.task_rect), if_then_else(c, t.device_pixel_scale, e.device_pixel_scale), if_then_else(c, t.screen_origin, e.screen_origin)); |
| 154 | }}; |
| 155 | // sampler2D sGpuBufferF; |
| 156 | // isampler2D sGpuBufferI; |
| 157 | // sampler2D sPathEdges; |
| 158 | struct PathTile_scalar { |
| 159 | vec4_scalar rect; |
| 160 | ivec2_scalar edges; |
| 161 | int32_t backdrop; |
| 162 | int32_t path_address; |
| 163 | PathTile_scalar() = default; |
| 164 | PathTile_scalar(vec4_scalar rect, ivec2_scalar edges, int32_t backdrop, int32_t path_address) : rect(rect), edges(edges), backdrop(backdrop), path_address(path_address){} |
| 165 | }; |
| 166 | struct PathTile { |
| 167 | vec4 rect; |
| 168 | ivec2 edges; |
| 169 | I32 backdrop; |
| 170 | I32 path_address; |
| 171 | PathTile() = default; |
| 172 | PathTile(vec4 rect, ivec2 edges, I32 backdrop, I32 path_address) : rect(rect), edges(edges), backdrop(backdrop), path_address(path_address){} |
| 173 | PathTile(vec4_scalar rect, ivec2_scalar edges, int32_t backdrop, int32_t path_address):rect(rect),edges(edges),backdrop(backdrop),path_address(path_address){ |
| 174 | } |
| 175 | IMPLICIT PathTile(PathTile_scalar s):rect(s.rect),edges(s.edges),backdrop(s.backdrop),path_address(s.path_address){ |
| 176 | } |
| 177 | friend PathTile if_then_else(I32 c, PathTile t, PathTile e) { return PathTile( |
| 178 | if_then_else(c, t.rect, e.rect), if_then_else(c, t.edges, e.edges), if_then_else(c, t.backdrop, e.backdrop), if_then_else(c, t.path_address, e.path_address)); |
| 179 | }}; |
| 180 | struct PathInfo_scalar { |
| 181 | int32_t render_task_address; |
| 182 | int32_t fill_rule; |
| 183 | float opacity; |
| 184 | PathInfo_scalar() = default; |
| 185 | PathInfo_scalar(int32_t render_task_address, int32_t fill_rule, float opacity) : render_task_address(render_task_address), fill_rule(fill_rule), opacity(opacity){} |
| 186 | }; |
| 187 | struct PathInfo { |
| 188 | I32 render_task_address; |
| 189 | I32 fill_rule; |
| 190 | Float opacity; |
| 191 | PathInfo() = default; |
| 192 | PathInfo(I32 render_task_address, I32 fill_rule, Float opacity) : render_task_address(render_task_address), fill_rule(fill_rule), opacity(opacity){} |
| 193 | PathInfo(int32_t render_task_address, int32_t fill_rule, float opacity):render_task_address(render_task_address),fill_rule(fill_rule),opacity(opacity){ |
| 194 | } |
| 195 | IMPLICIT PathInfo(PathInfo_scalar s):render_task_address(s.render_task_address),fill_rule(s.fill_rule),opacity(s.opacity){ |
| 196 | } |
| 197 | friend PathInfo if_then_else(I32 c, PathInfo t, PathInfo e) { return PathInfo( |
| 198 | if_then_else(c, t.render_task_address, e.render_task_address), if_then_else(c, t.fill_rule, e.fill_rule), if_then_else(c, t.opacity, e.opacity)); |
| 199 | }}; |
| 200 | vec2 vUv; |
| 201 | // ivec4_scalar vTileData; |
| 202 | ivec4_scalar aData; |
| 203 | PathTile_scalar decode_path_tile(ivec4_scalar data) { |
| 204 | PathTile_scalar tile; |
| 205 | vec2_scalar offset = make_vec2(make_float((((data).x)>>(10))&(1023)), make_float(((data).x)&(1023))); |
| 206 | float extend_x = make_float((((data).x)>>(20))&(1023)); |
| 207 | (tile).rect = (make_vec4((offset).x, (offset).y, (((offset).x)+(1.f))+(extend_x), ((offset).y)+(1.f)))*(16.f); |
| 208 | int32_t edge_count = (((data).z)>>(16))&(65535); |
| 209 | (tile).edges = make_ivec2((data).y, ((data).y)+(edge_count)); |
| 210 | (tile).backdrop = (((data).z)&(65535))-(128); |
| 211 | (tile).path_address = (data).w; |
| 212 | return tile; |
| 213 | } |
| 214 | ivec2_scalar get_gpu_buffer_uv(int32_t address) { |
| 215 | return make_ivec2((make_uint(address))%(1024u), (make_uint(address))/(1024u)); |
| 216 | } |
| 217 | ivec4_scalar fetch_from_gpu_buffer_1i(int32_t address) { |
| 218 | ivec2_scalar uv = get_gpu_buffer_uv(address); |
| 219 | return texelFetch(sGpuBufferI, uv, 0); |
| 220 | } |
| 221 | PathInfo_scalar fetch_path_info(int32_t address) { |
| 222 | ivec4_scalar data = fetch_from_gpu_buffer_1i(address); |
| 223 | PathInfo_scalar path; |
| 224 | (path).render_task_address = (data).x; |
| 225 | (path).fill_rule = (data).y; |
| 226 | (path).opacity = (make_float((data).z))/(65535.f); |
| 227 | return path; |
| 228 | } |
| 229 | RectWithEndpoint_scalar fetch_render_task_rect(int32_t index) { |
| 230 | ivec2_scalar uv = make_ivec2(make_int((2u)*((make_uint(index))%((1024u)/(2u)))), make_int((make_uint(index))/((1024u)/(2u)))); |
| 231 | auto sRenderTasks_uv_fetch = texelFetchPtr(sRenderTasks, uv, 0, 1, 0, 0); |
| 232 | vec4_scalar texel0 = texelFetchUnchecked(sRenderTasks, sRenderTasks_uv_fetch, 0, 0); |
| 233 | vec4_scalar texel1 = texelFetchUnchecked(sRenderTasks, sRenderTasks_uv_fetch, 1, 0); |
Value stored to 'texel1' during its initialization is never read | |
| 234 | RectWithEndpoint_scalar task_rect = RectWithEndpoint_scalar((texel0).sel(X,Y), (texel0).sel(Z,W)); |
| 235 | return task_rect; |
| 236 | } |
| 237 | ALWAYS_INLINE__attribute__((always_inline)) inline void main(void) { |
| 238 | PathTile_scalar tile = decode_path_tile(aData); |
| 239 | PathInfo_scalar path = fetch_path_info((tile).path_address); |
| 240 | RectWithEndpoint_scalar task_rect = fetch_render_task_rect((path).render_task_address); |
| 241 | vec2_scalar task_size = ((task_rect).p1)-((task_rect).p0); |
| 242 | vec2_scalar p0 = min(((tile).rect).sel(X,Y), task_size); |
| 243 | vec2_scalar p1 = min(((tile).rect).sel(Z,W), task_size); |
| 244 | vec2 pos = mix(p0, p1, (aPosition).sel(X,Y)); |
| 245 | vUv = (pos)-(((tile).rect).sel(X,Y)); |
| 246 | vTileData = make_ivec4((tile).edges, (tile).backdrop, (path).fill_rule); |
| 247 | gl_Position = (uTransform)*(make_vec4(((task_rect).p0)+(pos), 0.f, 1.f)); |
| 248 | } |
| 249 | static void set_uniform_1i(VertexShaderImpl* impl, int index, int value) { |
| 250 | Self* self = (Self*)impl; |
| 251 | if (self->samplers.set_slot(index, value)) return; |
| 252 | switch (index) { |
| 253 | case 2: |
| 254 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sGpuBufferF |
| 255 | break; |
| 256 | case 3: |
| 257 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sGpuBufferI |
| 258 | break; |
| 259 | case 5: |
| 260 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sPathEdges |
| 261 | break; |
| 262 | case 1: |
| 263 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sRenderTasks |
| 264 | break; |
| 265 | case 4: |
| 266 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // uTransform |
| 267 | break; |
| 268 | } |
| 269 | } |
| 270 | static void set_uniform_4fv(VertexShaderImpl* impl, int index, const float *value) { |
| 271 | Self* self = (Self*)impl; |
| 272 | switch (index) { |
| 273 | case 2: |
| 274 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sGpuBufferF |
| 275 | break; |
| 276 | case 3: |
| 277 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sGpuBufferI |
| 278 | break; |
| 279 | case 5: |
| 280 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sPathEdges |
| 281 | break; |
| 282 | case 1: |
| 283 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sRenderTasks |
| 284 | break; |
| 285 | case 4: |
| 286 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // uTransform |
| 287 | break; |
| 288 | } |
| 289 | } |
| 290 | static void set_uniform_matrix4fv(VertexShaderImpl* impl, int index, const float *value) { |
| 291 | Self* self = (Self*)impl; |
| 292 | switch (index) { |
| 293 | case 2: |
| 294 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sGpuBufferF |
| 295 | break; |
| 296 | case 3: |
| 297 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sGpuBufferI |
| 298 | break; |
| 299 | case 5: |
| 300 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sPathEdges |
| 301 | break; |
| 302 | case 1: |
| 303 | assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0" , __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__ )); // sRenderTasks |
| 304 | break; |
| 305 | case 4: |
| 306 | self->uTransform = mat4_scalar::load_from_ptr(value); |
| 307 | break; |
| 308 | } |
| 309 | } |
| 310 | static void load_attribs(VertexShaderImpl* impl, VertexAttrib *attribs, uint32_t start, int instance, int count) {Self* self = (Self*)impl; |
| 311 | load_attrib(self->aPosition, attribs[self->attrib_locations.aPosition], start, instance, count); |
| 312 | load_flat_attrib(self->aData, attribs[self->attrib_locations.aData], start, instance, count); |
| 313 | } |
| 314 | public: |
| 315 | struct InterpOutputs { |
| 316 | vec2_scalar vUv; |
| 317 | }; |
| 318 | private: |
| 319 | ALWAYS_INLINE__attribute__((always_inline)) inline void store_interp_outputs(char* dest_ptr, size_t stride) { |
| 320 | for(int n = 0; n < 4; n++) { |
| 321 | auto* dest = reinterpret_cast<InterpOutputs*>(dest_ptr); |
| 322 | dest->vUv = get_nth(vUv, n); |
| 323 | dest_ptr += stride; |
| 324 | } |
| 325 | } |
| 326 | static void run(VertexShaderImpl* impl, char* interps, size_t interp_stride) { |
| 327 | Self* self = (Self*)impl; |
| 328 | self->main(); |
| 329 | self->store_interp_outputs(interps, interp_stride); |
| 330 | } |
| 331 | static void init_batch(VertexShaderImpl* impl) { |
| 332 | Self* self = (Self*)impl; self->bind_textures(); } |
| 333 | public: |
| 334 | cs_path_tile_vert() { |
| 335 | set_uniform_1i_func = &set_uniform_1i; |
| 336 | set_uniform_4fv_func = &set_uniform_4fv; |
| 337 | set_uniform_matrix4fv_func = &set_uniform_matrix4fv; |
| 338 | init_batch_func = &init_batch; |
| 339 | load_attribs_func = &load_attribs; |
| 340 | run_primitive_func = &run; |
| 341 | } |
| 342 | }; |
| 343 | |
| 344 | |
| 345 | struct cs_path_tile_frag : FragmentShaderImpl, cs_path_tile_vert { |
| 346 | private: |
| 347 | typedef cs_path_tile_frag Self; |
| 348 | #define oFragColorgl_FragColor gl_FragColor |
| 349 | // vec4 oFragColor; |
| 350 | struct RectWithSize_scalar { |
| 351 | vec2_scalar p0; |
| 352 | vec2_scalar size; |
| 353 | RectWithSize_scalar() = default; |
| 354 | RectWithSize_scalar(vec2_scalar p0, vec2_scalar size) : p0(p0), size(size){} |
| 355 | }; |
| 356 | struct RectWithSize { |
| 357 | vec2 p0; |
| 358 | vec2 size; |
| 359 | RectWithSize() = default; |
| 360 | RectWithSize(vec2 p0, vec2 size) : p0(p0), size(size){} |
| 361 | RectWithSize(vec2_scalar p0, vec2_scalar size):p0(p0),size(size){ |
| 362 | } |
| 363 | IMPLICIT RectWithSize(RectWithSize_scalar s):p0(s.p0),size(s.size){ |
| 364 | } |
| 365 | friend RectWithSize if_then_else(I32 c, RectWithSize t, RectWithSize e) { return RectWithSize( |
| 366 | if_then_else(c, t.p0, e.p0), if_then_else(c, t.size, e.size)); |
| 367 | }}; |
| 368 | struct RectWithEndpoint_scalar { |
| 369 | vec2_scalar p0; |
| 370 | vec2_scalar p1; |
| 371 | RectWithEndpoint_scalar() = default; |
| 372 | RectWithEndpoint_scalar(vec2_scalar p0, vec2_scalar p1) : p0(p0), p1(p1){} |
| 373 | }; |
| 374 | struct RectWithEndpoint { |
| 375 | vec2 p0; |
| 376 | vec2 p1; |
| 377 | RectWithEndpoint() = default; |
| 378 | RectWithEndpoint(vec2 p0, vec2 p1) : p0(p0), p1(p1){} |
| 379 | RectWithEndpoint(vec2_scalar p0, vec2_scalar p1):p0(p0),p1(p1){ |
| 380 | } |
| 381 | IMPLICIT RectWithEndpoint(RectWithEndpoint_scalar s):p0(s.p0),p1(s.p1){ |
| 382 | } |
| 383 | friend RectWithEndpoint if_then_else(I32 c, RectWithEndpoint t, RectWithEndpoint e) { return RectWithEndpoint( |
| 384 | if_then_else(c, t.p0, e.p0), if_then_else(c, t.p1, e.p1)); |
| 385 | }}; |
| 386 | // sampler2D sGpuBufferF; |
| 387 | // isampler2D sGpuBufferI; |
| 388 | // sampler2D sPathEdges; |
| 389 | vec2 vUv; |
| 390 | // ivec4_scalar vTileData; |
| 391 | Float rasterize_edge_analytical(vec2 p0, vec2 p1) { |
| 392 | I32 ret_mask = ~0; |
| 393 | Float ret; |
| 394 | Float y0 = clamp((p0).y, 0.f, 1.f); |
| 395 | Float y1 = clamp((p1).y, 0.f, 1.f); |
| 396 | auto _c2_ = (y0)==(y1); |
| 397 | { |
| 398 | ret = 0.f; |
| 399 | ret_mask = ~I32(_c2_); |
| 400 | } |
| 401 | Float inv_dy = (1.f)/(((p1).y)-((p0).y)); |
| 402 | Float t0 = ((y0)-((p0).y))*(inv_dy); |
| 403 | Float t1 = ((y1)-((p0).y))*(inv_dy); |
| 404 | Float x0 = (((p0).x)*((1.f)-(t0)))+(((p1).x)*(t0)); |
| 405 | Float x1 = (((p0).x)*((1.f)-(t1)))+(((p1).x)*(t1)); |
| 406 | float jitter = 0.00001f; |
| 407 | Float xmin = (min(min(x1, x0), 1.f))-(jitter); |
| 408 | Float xmax = max(x1, x0); |
| 409 | Float b = min(xmax, 1.f); |
| 410 | Float c = max(b, 0.f); |
| 411 | Float d = max(xmin, 0.f); |
| 412 | Float area = (((b)+((0.5f)*(((d)*(d))-((c)*(c)))))-(xmin))/((xmax)-(xmin)); |
| 413 | ret = if_then_else(ret_mask, (area)*((y1)-(y0)), ret); |
| 414 | return ret; |
| 415 | } |
| 416 | Float path_resolve_mask(Float winding_number, int32_t fill_rule) { |
| 417 | Float mask; |
| 418 | if (((fill_rule)&(1))==(0)) { |
| 419 | { |
| 420 | mask = (1.f)-(abs__glsl_abs((mod(abs__glsl_abs(winding_number), 2.f))-(1.f))); |
| 421 | } |
| 422 | } else { |
| 423 | mask = min(abs__glsl_abs(winding_number), 1.f); |
| 424 | } |
| 425 | if (((fill_rule)&(2))!=(0)) { |
| 426 | { |
| 427 | mask = (1.f)-(mask); |
| 428 | } |
| 429 | } |
| 430 | return mask; |
| 431 | } |
| 432 | Float path_tile_coverage(vec2 uv, ivec2_scalar edges, int32_t backdrop, int32_t fill_rule) { |
| 433 | Float winding_number = make_float(backdrop); |
| 434 | vec2 pixel_offset = (uv)-(make_vec2(0.5f)); |
| 435 | int32_t end = min((edges).y, ((edges).x)+(512)); |
| 436 | for ( int32_t edge_idx = (edges).x; |
| 437 | (edge_idx)<(end); edge_idx++) { |
| 438 | ivec2_scalar edge_uv = make_ivec2(make_int((make_uint(edge_idx))%(1024u)), make_int((make_uint(edge_idx))/(1024u))); |
| 439 | vec4_scalar edge = (texelFetch(sPathEdges, edge_uv, 0))*((255.f)/(15.f)); |
| 440 | winding_number += rasterize_edge_analytical(((edge).sel(X,Y))-(pixel_offset), ((edge).sel(Z,W))-(pixel_offset)); |
| 441 | } |
| 442 | return path_resolve_mask(winding_number, fill_rule); |
| 443 | } |
| 444 | ALWAYS_INLINE__attribute__((always_inline)) inline void main(void) { |
| 445 | Float mask = path_tile_coverage(vUv, (vTileData).sel(X,Y), (vTileData).z, (vTileData).w); |
| 446 | oFragColorgl_FragColor = make_vec4(make_vec3((1.f)-(mask)), mask); |
| 447 | } |
| 448 | typedef cs_path_tile_vert::InterpOutputs InterpInputs; |
| 449 | InterpInputs interp_step; |
| 450 | struct InterpPerspective { |
| 451 | vec2 vUv; |
| 452 | }; |
| 453 | InterpPerspective interp_perspective; |
| 454 | static void read_interp_inputs(FragmentShaderImpl* impl, const void* init_, const void* step_) {Self* self = (Self*)impl;const InterpInputs* init = (const InterpInputs*)init_;const InterpInputs* step = (const InterpInputs*)step_; |
| 455 | self->vUv = init_interp(init->vUv, step->vUv); |
| 456 | self->interp_step.vUv = step->vUv * 4.0f; |
| 457 | } |
| 458 | static void read_perspective_inputs(FragmentShaderImpl* impl, const void* init_, const void* step_) {Self* self = (Self*)impl;const InterpInputs* init = (const InterpInputs*)init_;const InterpInputs* step = (const InterpInputs*)step_; |
| 459 | Float w = 1.0f / self->gl_FragCoord.w; |
| 460 | self->interp_perspective.vUv = init_interp(init->vUv, step->vUv); |
| 461 | self->vUv = self->interp_perspective.vUv * w; |
| 462 | self->interp_step.vUv = step->vUv * 4.0f; |
| 463 | } |
| 464 | ALWAYS_INLINE__attribute__((always_inline)) inline void step_interp_inputs(int steps = 4) { |
| 465 | float chunks = steps * 0.25f; |
| 466 | vUv += interp_step.vUv * chunks; |
| 467 | } |
| 468 | ALWAYS_INLINE__attribute__((always_inline)) inline void step_perspective_inputs(int steps = 4) { |
| 469 | step_perspective(steps); |
| 470 | float chunks = steps * 0.25f; |
| 471 | Float w = 1.0f / gl_FragCoord.w; |
| 472 | interp_perspective.vUv += interp_step.vUv * chunks; |
| 473 | vUv = w * interp_perspective.vUv; |
| 474 | } |
| 475 | static void run(FragmentShaderImpl* impl) { |
| 476 | Self* self = (Self*)impl; |
| 477 | self->main(); |
| 478 | self->step_interp_inputs(); |
| 479 | } |
| 480 | static void skip(FragmentShaderImpl* impl, int steps) { |
| 481 | Self* self = (Self*)impl; |
| 482 | self->step_interp_inputs(steps); |
| 483 | } |
| 484 | static void run_perspective(FragmentShaderImpl* impl) { |
| 485 | Self* self = (Self*)impl; |
| 486 | self->main(); |
| 487 | self->step_perspective_inputs(); |
| 488 | } |
| 489 | static void skip_perspective(FragmentShaderImpl* impl, int steps) { |
| 490 | Self* self = (Self*)impl; |
| 491 | self->step_perspective_inputs(steps); |
| 492 | } |
| 493 | public: |
| 494 | cs_path_tile_frag() { |
| 495 | init_span_func = &read_interp_inputs; |
| 496 | run_func = &run; |
| 497 | skip_func = &skip; |
| 498 | enable_perspective(); |
| 499 | init_span_w_func = &read_perspective_inputs; |
| 500 | run_w_func = &run_perspective; |
| 501 | skip_w_func = &skip_perspective; |
| 502 | } |
| 503 | }; |
| 504 | |
| 505 | struct cs_path_tile_program : ProgramImpl, cs_path_tile_frag { |
| 506 | int get_uniform(const char *name) const override { |
| 507 | if (strcmp("sGpuBufferF", name) == 0) { return 2; } |
| 508 | if (strcmp("sGpuBufferI", name) == 0) { return 3; } |
| 509 | if (strcmp("sPathEdges", name) == 0) { return 5; } |
| 510 | if (strcmp("sRenderTasks", name) == 0) { return 1; } |
| 511 | if (strcmp("uTransform", name) == 0) { return 4; } |
| 512 | return -1; |
| 513 | } |
| 514 | void bind_attrib(const char* name, int index) override { |
| 515 | attrib_locations.bind_loc(name, index); |
| 516 | } |
| 517 | int get_attrib(const char* name) const override { |
| 518 | return attrib_locations.get_loc(name); |
| 519 | } |
| 520 | size_t interpolants_size() const override { return sizeof(InterpOutputs); } |
| 521 | VertexShaderImpl* get_vertex_shader() override { |
| 522 | return this; |
| 523 | } |
| 524 | FragmentShaderImpl* get_fragment_shader() override { |
| 525 | return this; |
| 526 | } |
| 527 | const char* get_name() const override { return "cs_path_tile"; } |
| 528 | static ProgramImpl* loader() { return new cs_path_tile_program; } |
| 529 | }; |
| 530 |