Copy as Markdown

Other Tools

struct ps_quad_mask_common {
struct Samplers {
sampler2D_impl sGpuBufferF_impl;
int sGpuBufferF_slot;
isampler2D_impl sGpuBufferI_impl;
int sGpuBufferI_slot;
sampler2D_impl sRenderTasks_impl;
int sRenderTasks_slot;
sampler2D_impl sTransformPalette_impl;
int sTransformPalette_slot;
bool set_slot(int index, int value) {
switch (index) {
case 3:
sGpuBufferF_slot = value;
return true;
case 4:
sGpuBufferI_slot = value;
return true;
case 2:
sRenderTasks_slot = value;
return true;
case 1:
sTransformPalette_slot = value;
return true;
}
return false;
}
} samplers;
struct AttribLocations {
int aPosition = NULL_ATTRIB;
int aData = NULL_ATTRIB;
int aClipData = NULL_ATTRIB;
void bind_loc(const char* name, int index) {
if (strcmp("aPosition", name) == 0) { aPosition = index; return; }
if (strcmp("aData", name) == 0) { aData = index; return; }
if (strcmp("aClipData", name) == 0) { aClipData = index; return; }
}
int get_loc(const char* name) const {
if (strcmp("aPosition", name) == 0) { return aPosition != NULL_ATTRIB ? aPosition : -1; }
if (strcmp("aData", name) == 0) { return aData != NULL_ATTRIB ? aData : -1; }
if (strcmp("aClipData", name) == 0) { return aClipData != NULL_ATTRIB ? aClipData : -1; }
return -1;
}
} attrib_locations;
vec4_scalar vTransformBounds;
vec4_scalar v_color;
vec4_scalar vClipCenter_Radius_TL;
vec4_scalar vClipCenter_Radius_TR;
vec4_scalar vClipCenter_Radius_BR;
vec4_scalar vClipCenter_Radius_BL;
vec4_scalar vClipPlane_A;
vec4_scalar vClipPlane_B;
vec4_scalar vClipPlane_C;
vec2_scalar vClipMode;
sampler2D sGpuBufferF;
isampler2D sGpuBufferI;
sampler2D sRenderTasks;
sampler2D sTransformPalette;
mat4_scalar uTransform;
void bind_textures() {
sGpuBufferF = lookup_sampler(&samplers.sGpuBufferF_impl, samplers.sGpuBufferF_slot);
sGpuBufferI = lookup_isampler(&samplers.sGpuBufferI_impl, samplers.sGpuBufferI_slot);
sRenderTasks = lookup_sampler(&samplers.sRenderTasks_impl, samplers.sRenderTasks_slot);
sTransformPalette = lookup_sampler(&samplers.sTransformPalette_impl, samplers.sTransformPalette_slot);
}
};
struct ps_quad_mask_vert : VertexShaderImpl, ps_quad_mask_common {
private:
typedef ps_quad_mask_vert Self;
// mat4_scalar uTransform;
vec2 aPosition;
// sampler2D sColor0;
// sampler2D sColor1;
// sampler2D sColor2;
struct RectWithSize_scalar {
vec2_scalar p0;
vec2_scalar size;
RectWithSize_scalar() = default;
RectWithSize_scalar(vec2_scalar p0, vec2_scalar size) : p0(p0), size(size){}
};
struct RectWithSize {
vec2 p0;
vec2 size;
RectWithSize() = default;
RectWithSize(vec2 p0, vec2 size) : p0(p0), size(size){}
RectWithSize(vec2_scalar p0, vec2_scalar size):p0(p0),size(size){
}
IMPLICIT RectWithSize(RectWithSize_scalar s):p0(s.p0),size(s.size){
}
friend RectWithSize if_then_else(I32 c, RectWithSize t, RectWithSize e) { return RectWithSize(
if_then_else(c, t.p0, e.p0), if_then_else(c, t.size, e.size));
}};
struct RectWithEndpoint_scalar {
vec2_scalar p0;
vec2_scalar p1;
RectWithEndpoint_scalar() = default;
RectWithEndpoint_scalar(vec2_scalar p0, vec2_scalar p1) : p0(p0), p1(p1){}
};
struct RectWithEndpoint {
vec2 p0;
vec2 p1;
RectWithEndpoint() = default;
RectWithEndpoint(vec2 p0, vec2 p1) : p0(p0), p1(p1){}
RectWithEndpoint(vec2_scalar p0, vec2_scalar p1):p0(p0),p1(p1){
}
IMPLICIT RectWithEndpoint(RectWithEndpoint_scalar s):p0(s.p0),p1(s.p1){
}
friend RectWithEndpoint if_then_else(I32 c, RectWithEndpoint t, RectWithEndpoint e) { return RectWithEndpoint(
if_then_else(c, t.p0, e.p0), if_then_else(c, t.p1, e.p1));
}};
// vec4_scalar vTransformBounds;
// sampler2D sTransformPalette;
struct Transform_scalar {
mat4_scalar m;
mat4_scalar inv_m;
bool is_axis_aligned;
Transform_scalar() = default;
Transform_scalar(mat4_scalar m, mat4_scalar inv_m, bool is_axis_aligned) : m(m), inv_m(inv_m), is_axis_aligned(is_axis_aligned){}
};
struct Transform {
mat4 m;
mat4 inv_m;
Bool is_axis_aligned;
Transform() = default;
Transform(mat4 m, mat4 inv_m, Bool is_axis_aligned) : m(m), inv_m(inv_m), is_axis_aligned(is_axis_aligned){}
Transform(mat4_scalar m, mat4_scalar inv_m, bool is_axis_aligned):m(m),inv_m(inv_m),is_axis_aligned(is_axis_aligned){
}
IMPLICIT Transform(Transform_scalar s):m(s.m),inv_m(s.inv_m),is_axis_aligned(s.is_axis_aligned){
}
friend Transform if_then_else(I32 c, Transform t, Transform e) { return Transform(
if_then_else(c, t.m, e.m), if_then_else(c, t.inv_m, e.inv_m), if_then_else(c, t.is_axis_aligned, e.is_axis_aligned));
}};
// sampler2D sRenderTasks;
struct RenderTaskData_scalar {
RectWithEndpoint_scalar task_rect;
vec4_scalar user_data;
RenderTaskData_scalar() = default;
RenderTaskData_scalar(RectWithEndpoint_scalar task_rect, vec4_scalar user_data) : task_rect(task_rect), user_data(user_data){}
};
struct RenderTaskData {
RectWithEndpoint task_rect;
vec4 user_data;
RenderTaskData() = default;
RenderTaskData(RectWithEndpoint task_rect, vec4 user_data) : task_rect(task_rect), user_data(user_data){}
RenderTaskData(RectWithEndpoint_scalar task_rect, vec4_scalar user_data):task_rect(task_rect),user_data(user_data){
}
IMPLICIT RenderTaskData(RenderTaskData_scalar s):task_rect(s.task_rect),user_data(s.user_data){
}
friend RenderTaskData if_then_else(I32 c, RenderTaskData t, RenderTaskData e) { return RenderTaskData(
if_then_else(c, t.task_rect, e.task_rect), if_then_else(c, t.user_data, e.user_data));
}};
struct PictureTask_scalar {
RectWithEndpoint_scalar task_rect;
float device_pixel_scale;
vec2_scalar content_origin;
PictureTask_scalar() = default;
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){}
};
struct PictureTask {
RectWithEndpoint task_rect;
Float device_pixel_scale;
vec2 content_origin;
PictureTask() = default;
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){}
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){
}
IMPLICIT PictureTask(PictureTask_scalar s):task_rect(s.task_rect),device_pixel_scale(s.device_pixel_scale),content_origin(s.content_origin){
}
friend PictureTask if_then_else(I32 c, PictureTask t, PictureTask e) { return PictureTask(
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));
}};
struct ClipArea_scalar {
RectWithEndpoint_scalar task_rect;
float device_pixel_scale;
vec2_scalar screen_origin;
ClipArea_scalar() = default;
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){}
};
struct ClipArea {
RectWithEndpoint task_rect;
Float device_pixel_scale;
vec2 screen_origin;
ClipArea() = default;
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){}
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){
}
IMPLICIT ClipArea(ClipArea_scalar s):task_rect(s.task_rect),device_pixel_scale(s.device_pixel_scale),screen_origin(s.screen_origin){
}
friend ClipArea if_then_else(I32 c, ClipArea t, ClipArea e) { return ClipArea(
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));
}};
// sampler2D sGpuBufferF;
// isampler2D sGpuBufferI;
// vec4_scalar v_color;
// ivec4_scalar v_flags;
ivec4_scalar aData;
struct QuadSegment_scalar {
RectWithEndpoint_scalar rect;
RectWithEndpoint_scalar uv_rect;
QuadSegment_scalar() = default;
QuadSegment_scalar(RectWithEndpoint_scalar rect, RectWithEndpoint_scalar uv_rect) : rect(rect), uv_rect(uv_rect){}
};
struct QuadSegment {
RectWithEndpoint rect;
RectWithEndpoint uv_rect;
QuadSegment() = default;
QuadSegment(RectWithEndpoint rect, RectWithEndpoint uv_rect) : rect(rect), uv_rect(uv_rect){}
QuadSegment(RectWithEndpoint_scalar rect, RectWithEndpoint_scalar uv_rect):rect(rect),uv_rect(uv_rect){
}
IMPLICIT QuadSegment(QuadSegment_scalar s):rect(s.rect),uv_rect(s.uv_rect){
}
friend QuadSegment if_then_else(I32 c, QuadSegment t, QuadSegment e) { return QuadSegment(
if_then_else(c, t.rect, e.rect), if_then_else(c, t.uv_rect, e.uv_rect));
}};
struct PrimitiveInfo_scalar {
vec2_scalar local_pos;
RectWithEndpoint_scalar local_prim_rect;
RectWithEndpoint_scalar local_clip_rect;
QuadSegment_scalar segment;
int32_t edge_flags;
int32_t quad_flags;
ivec2_scalar pattern_input;
PrimitiveInfo_scalar() = default;
PrimitiveInfo_scalar(vec2_scalar local_pos, RectWithEndpoint_scalar local_prim_rect, RectWithEndpoint_scalar local_clip_rect, QuadSegment_scalar segment, int32_t edge_flags, int32_t quad_flags, ivec2_scalar pattern_input) : local_pos(local_pos), local_prim_rect(local_prim_rect), local_clip_rect(local_clip_rect), segment(segment), edge_flags(edge_flags), quad_flags(quad_flags), pattern_input(pattern_input){}
};
struct PrimitiveInfo {
vec2 local_pos;
RectWithEndpoint local_prim_rect;
RectWithEndpoint local_clip_rect;
QuadSegment segment;
I32 edge_flags;
I32 quad_flags;
ivec2 pattern_input;
PrimitiveInfo() = default;
PrimitiveInfo(vec2 local_pos, RectWithEndpoint local_prim_rect, RectWithEndpoint local_clip_rect, QuadSegment segment, I32 edge_flags, I32 quad_flags, ivec2 pattern_input) : local_pos(local_pos), local_prim_rect(local_prim_rect), local_clip_rect(local_clip_rect), segment(segment), edge_flags(edge_flags), quad_flags(quad_flags), pattern_input(pattern_input){}
PrimitiveInfo(vec2_scalar local_pos, RectWithEndpoint_scalar local_prim_rect, RectWithEndpoint_scalar local_clip_rect, QuadSegment_scalar segment, int32_t edge_flags, int32_t quad_flags, ivec2_scalar pattern_input):local_pos(local_pos),local_prim_rect(local_prim_rect),local_clip_rect(local_clip_rect),segment(segment),edge_flags(edge_flags),quad_flags(quad_flags),pattern_input(pattern_input){
}
IMPLICIT PrimitiveInfo(PrimitiveInfo_scalar s):local_pos(s.local_pos),local_prim_rect(s.local_prim_rect),local_clip_rect(s.local_clip_rect),segment(s.segment),edge_flags(s.edge_flags),quad_flags(s.quad_flags),pattern_input(s.pattern_input){
}
friend PrimitiveInfo if_then_else(I32 c, PrimitiveInfo t, PrimitiveInfo e) { return PrimitiveInfo(
if_then_else(c, t.local_pos, e.local_pos), if_then_else(c, t.local_prim_rect, e.local_prim_rect), if_then_else(c, t.local_clip_rect, e.local_clip_rect), if_then_else(c, t.segment, e.segment), if_then_else(c, t.edge_flags, e.edge_flags), if_then_else(c, t.quad_flags, e.quad_flags), if_then_else(c, t.pattern_input, e.pattern_input));
}};
struct QuadPrimitive_scalar {
RectWithEndpoint_scalar bounds;
RectWithEndpoint_scalar clip;
vec4_scalar color;
QuadPrimitive_scalar() = default;
QuadPrimitive_scalar(RectWithEndpoint_scalar bounds, RectWithEndpoint_scalar clip, vec4_scalar color) : bounds(bounds), clip(clip), color(color){}
};
struct QuadPrimitive {
RectWithEndpoint bounds;
RectWithEndpoint clip;
vec4 color;
QuadPrimitive() = default;
QuadPrimitive(RectWithEndpoint bounds, RectWithEndpoint clip, vec4 color) : bounds(bounds), clip(clip), color(color){}
QuadPrimitive(RectWithEndpoint_scalar bounds, RectWithEndpoint_scalar clip, vec4_scalar color):bounds(bounds),clip(clip),color(color){
}
IMPLICIT QuadPrimitive(QuadPrimitive_scalar s):bounds(s.bounds),clip(s.clip),color(s.color){
}
friend QuadPrimitive if_then_else(I32 c, QuadPrimitive t, QuadPrimitive e) { return QuadPrimitive(
if_then_else(c, t.bounds, e.bounds), if_then_else(c, t.clip, e.clip), if_then_else(c, t.color, e.color));
}};
struct QuadHeader_scalar {
int32_t transform_id;
int32_t z_id;
ivec2_scalar pattern_input;
QuadHeader_scalar() = default;
QuadHeader_scalar(int32_t transform_id, int32_t z_id, ivec2_scalar pattern_input) : transform_id(transform_id), z_id(z_id), pattern_input(pattern_input){}
};
struct QuadHeader {
I32 transform_id;
I32 z_id;
ivec2 pattern_input;
QuadHeader() = default;
QuadHeader(I32 transform_id, I32 z_id, ivec2 pattern_input) : transform_id(transform_id), z_id(z_id), pattern_input(pattern_input){}
QuadHeader(int32_t transform_id, int32_t z_id, ivec2_scalar pattern_input):transform_id(transform_id),z_id(z_id),pattern_input(pattern_input){
}
IMPLICIT QuadHeader(QuadHeader_scalar s):transform_id(s.transform_id),z_id(s.z_id),pattern_input(s.pattern_input){
}
friend QuadHeader if_then_else(I32 c, QuadHeader t, QuadHeader e) { return QuadHeader(
if_then_else(c, t.transform_id, e.transform_id), if_then_else(c, t.z_id, e.z_id), if_then_else(c, t.pattern_input, e.pattern_input));
}};
struct QuadInstance_scalar {
int32_t prim_address_i;
int32_t prim_address_f;
int32_t quad_flags;
int32_t edge_flags;
int32_t part_index;
int32_t segment_index;
int32_t picture_task_address;
QuadInstance_scalar() = default;
QuadInstance_scalar(int32_t prim_address_i, int32_t prim_address_f, int32_t quad_flags, int32_t edge_flags, int32_t part_index, int32_t segment_index, int32_t picture_task_address) : prim_address_i(prim_address_i), prim_address_f(prim_address_f), quad_flags(quad_flags), edge_flags(edge_flags), part_index(part_index), segment_index(segment_index), picture_task_address(picture_task_address){}
};
struct QuadInstance {
I32 prim_address_i;
I32 prim_address_f;
I32 quad_flags;
I32 edge_flags;
I32 part_index;
I32 segment_index;
I32 picture_task_address;
QuadInstance() = default;
QuadInstance(I32 prim_address_i, I32 prim_address_f, I32 quad_flags, I32 edge_flags, I32 part_index, I32 segment_index, I32 picture_task_address) : prim_address_i(prim_address_i), prim_address_f(prim_address_f), quad_flags(quad_flags), edge_flags(edge_flags), part_index(part_index), segment_index(segment_index), picture_task_address(picture_task_address){}
QuadInstance(int32_t prim_address_i, int32_t prim_address_f, int32_t quad_flags, int32_t edge_flags, int32_t part_index, int32_t segment_index, int32_t picture_task_address):prim_address_i(prim_address_i),prim_address_f(prim_address_f),quad_flags(quad_flags),edge_flags(edge_flags),part_index(part_index),segment_index(segment_index),picture_task_address(picture_task_address){
}
IMPLICIT QuadInstance(QuadInstance_scalar s):prim_address_i(s.prim_address_i),prim_address_f(s.prim_address_f),quad_flags(s.quad_flags),edge_flags(s.edge_flags),part_index(s.part_index),segment_index(s.segment_index),picture_task_address(s.picture_task_address){
}
friend QuadInstance if_then_else(I32 c, QuadInstance t, QuadInstance e) { return QuadInstance(
if_then_else(c, t.prim_address_i, e.prim_address_i), if_then_else(c, t.prim_address_f, e.prim_address_f), if_then_else(c, t.quad_flags, e.quad_flags), if_then_else(c, t.edge_flags, e.edge_flags), if_then_else(c, t.part_index, e.part_index), if_then_else(c, t.segment_index, e.segment_index), if_then_else(c, t.picture_task_address, e.picture_task_address));
}};
struct VertexInfo_scalar {
vec2_scalar local_pos;
VertexInfo_scalar() = default;
explicit VertexInfo_scalar(vec2_scalar local_pos) : local_pos(local_pos){}
};
struct VertexInfo {
vec2 local_pos;
VertexInfo() = default;
explicit VertexInfo(vec2 local_pos) : local_pos(local_pos){}
explicit VertexInfo(vec2_scalar local_pos):local_pos(local_pos){
}
IMPLICIT VertexInfo(VertexInfo_scalar s):local_pos(s.local_pos){
}
friend VertexInfo if_then_else(I32 c, VertexInfo t, VertexInfo e) { return VertexInfo(
if_then_else(c, t.local_pos, e.local_pos));
}};
vec4 vClipLocalPos;
// vec4_scalar vClipCenter_Radius_TL;
// vec4_scalar vClipCenter_Radius_TR;
// vec4_scalar vClipCenter_Radius_BR;
// vec4_scalar vClipCenter_Radius_BL;
// vec4_scalar vClipPlane_A;
// vec4_scalar vClipPlane_B;
// vec4_scalar vClipPlane_C;
// vec2_scalar vClipMode;
ivec4_scalar aClipData;
struct Clip_scalar {
RectWithEndpoint_scalar rect;
vec4_scalar radii_top;
vec4_scalar radii_bottom;
float mode;
int32_t space;
Clip_scalar() = default;
Clip_scalar(RectWithEndpoint_scalar rect, vec4_scalar radii_top, vec4_scalar radii_bottom, float mode, int32_t space) : rect(rect), radii_top(radii_top), radii_bottom(radii_bottom), mode(mode), space(space){}
};
struct Clip {
RectWithEndpoint rect;
vec4 radii_top;
vec4 radii_bottom;
Float mode;
I32 space;
Clip() = default;
Clip(RectWithEndpoint rect, vec4 radii_top, vec4 radii_bottom, Float mode, I32 space) : rect(rect), radii_top(radii_top), radii_bottom(radii_bottom), mode(mode), space(space){}
Clip(RectWithEndpoint_scalar rect, vec4_scalar radii_top, vec4_scalar radii_bottom, float mode, int32_t space):rect(rect),radii_top(radii_top),radii_bottom(radii_bottom),mode(mode),space(space){
}
IMPLICIT Clip(Clip_scalar s):rect(s.rect),radii_top(s.radii_top),radii_bottom(s.radii_bottom),mode(s.mode),space(s.space){
}
friend Clip if_then_else(I32 c, Clip t, Clip e) { return Clip(
if_then_else(c, t.rect, e.rect), if_then_else(c, t.radii_top, e.radii_top), if_then_else(c, t.radii_bottom, e.radii_bottom), if_then_else(c, t.mode, e.mode), if_then_else(c, t.space, e.space));
}};
QuadInstance_scalar decode_instance() {
QuadInstance_scalar qi = QuadInstance_scalar((aData).x, (aData).y, (((aData).z)>>(24))&(255), (((aData).z)>>(16))&(255), (((aData).z)>>(8))&(255), (((aData).z)>>(0))&(255), (aData).w);
return qi;
}
ivec2_scalar get_gpu_buffer_uv(int32_t address) {
return make_ivec2((make_uint(address))%(1024u), (make_uint(address))/(1024u));
}
ivec4_scalar fetch_from_gpu_buffer_1i(int32_t address) {
ivec2_scalar uv = get_gpu_buffer_uv(address);
return texelFetch(sGpuBufferI, uv, 0);
}
QuadHeader_scalar fetch_header(int32_t address) {
ivec4_scalar header = fetch_from_gpu_buffer_1i(address);
QuadHeader_scalar qh = QuadHeader_scalar((header).x, (header).y, (header).sel(Z,W));
return qh;
}
Transform_scalar fetch_transform(int32_t id) {
Transform_scalar transform;
(transform).is_axis_aligned = ((id)>>(23))==(0);
int32_t index = (id)&(8388607);
ivec2_scalar uv = make_ivec2(make_int((8u)*((make_uint(index))%((1024u)/(8u)))), make_int((make_uint(index))/((1024u)/(8u))));
ivec2_scalar uv0 = make_ivec2(((uv).x)+(0), (uv).y);
auto sTransformPalette_uv0_fetch = texelFetchPtr(sTransformPalette, uv0, 0, 7, 0, 0);
(transform).m[0] = texelFetchUnchecked(sTransformPalette, sTransformPalette_uv0_fetch, 0, 0);
(transform).m[1] = texelFetchUnchecked(sTransformPalette, sTransformPalette_uv0_fetch, 1, 0);
(transform).m[2] = texelFetchUnchecked(sTransformPalette, sTransformPalette_uv0_fetch, 2, 0);
(transform).m[3] = texelFetchUnchecked(sTransformPalette, sTransformPalette_uv0_fetch, 3, 0);
(transform).inv_m[0] = texelFetchUnchecked(sTransformPalette, sTransformPalette_uv0_fetch, 4, 0);
(transform).inv_m[1] = texelFetchUnchecked(sTransformPalette, sTransformPalette_uv0_fetch, 5, 0);
(transform).inv_m[2] = texelFetchUnchecked(sTransformPalette, sTransformPalette_uv0_fetch, 6, 0);
(transform).inv_m[3] = texelFetchUnchecked(sTransformPalette, sTransformPalette_uv0_fetch, 7, 0);
return transform;
}
RenderTaskData_scalar fetch_render_task_data(int32_t index) {
ivec2_scalar uv = make_ivec2(make_int((2u)*((make_uint(index))%((1024u)/(2u)))), make_int((make_uint(index))/((1024u)/(2u))));
auto sRenderTasks_uv_fetch = texelFetchPtr(sRenderTasks, uv, 0, 1, 0, 0);
vec4_scalar texel0 = texelFetchUnchecked(sRenderTasks, sRenderTasks_uv_fetch, 0, 0);
vec4_scalar texel1 = texelFetchUnchecked(sRenderTasks, sRenderTasks_uv_fetch, 1, 0);
RectWithEndpoint_scalar task_rect = RectWithEndpoint_scalar((texel0).sel(X,Y), (texel0).sel(Z,W));
RenderTaskData_scalar data = RenderTaskData_scalar(task_rect, texel1);
return data;
}
PictureTask_scalar fetch_picture_task(int32_t address) {
RenderTaskData_scalar task_data = fetch_render_task_data(address);
PictureTask_scalar task = PictureTask_scalar((task_data).task_rect, ((task_data).user_data).x, ((task_data).user_data).sel(Y,Z));
return task;
}
Array<vec4_scalar,3> fetch_from_gpu_buffer_3f(int32_t address) {
ivec2_scalar uv = get_gpu_buffer_uv(address);
auto sGpuBufferF_uv_fetch = texelFetchPtr(sGpuBufferF, uv, 0, 2, 0, 0);
return Array<vec4_scalar,3>{{texelFetchUnchecked(sGpuBufferF, sGpuBufferF_uv_fetch, 0, 0), texelFetchUnchecked(sGpuBufferF, sGpuBufferF_uv_fetch, 1, 0), texelFetchUnchecked(sGpuBufferF, sGpuBufferF_uv_fetch, 2, 0)}};
}
QuadPrimitive_scalar fetch_primitive(int32_t index) {
QuadPrimitive_scalar prim;
Array<vec4_scalar,3> texels = fetch_from_gpu_buffer_3f(index);
(prim).bounds = RectWithEndpoint_scalar((texels[0]).sel(X,Y), (texels[0]).sel(Z,W));
(prim).clip = RectWithEndpoint_scalar((texels[1]).sel(X,Y), (texels[1]).sel(Z,W));
(prim).color = texels[2];
return prim;
}
Array<vec4_scalar,2> fetch_from_gpu_buffer_2f(int32_t address) {
ivec2_scalar uv = get_gpu_buffer_uv(address);
auto sGpuBufferF_uv_fetch = texelFetchPtr(sGpuBufferF, uv, 0, 1, 0, 0);
return Array<vec4_scalar,2>{{texelFetchUnchecked(sGpuBufferF, sGpuBufferF_uv_fetch, 0, 0), texelFetchUnchecked(sGpuBufferF, sGpuBufferF_uv_fetch, 1, 0)}};
}
QuadSegment_scalar fetch_segment(int32_t base, int32_t index) {
QuadSegment_scalar seg;
Array<vec4_scalar,2> texels = fetch_from_gpu_buffer_2f(((base)+(3))+((index)*(2)));
(seg).rect = RectWithEndpoint_scalar((texels[0]).sel(X,Y), (texels[0]).sel(Z,W));
(seg).uv_rect = RectWithEndpoint_scalar((texels[1]).sel(X,Y), (texels[1]).sel(Z,W));
return seg;
}
float edge_aa_offset(int32_t edge, int32_t flags) {
return ((flags)&(edge))!=(0) ? 2.f : 0.f;
}
vec2 rect_clamp(RectWithEndpoint_scalar rect, vec2 pt) {
return clamp(pt, (rect).p0, (rect).p1);
}
VertexInfo write_vertex(vec2 local_pos, float z, Transform_scalar transform, vec2_scalar content_origin, RectWithEndpoint_scalar task_rect, float device_pixel_scale, int32_t quad_flags) {
VertexInfo vi;
vec4 world_pos = ((transform).m)*(make_vec4(local_pos, 0.f, 1.f));
vec2 device_pos = ((world_pos).sel(X,Y))*(device_pixel_scale);
if (((quad_flags)&(2))!=(0)) {
{
RectWithEndpoint_scalar device_clip_rect = RectWithEndpoint_scalar(content_origin, ((content_origin)+((task_rect).p1))-((task_rect).p0));
device_pos = rect_clamp(device_clip_rect, device_pos);
(vi).local_pos = (((transform).inv_m)*(make_vec4((device_pos)/(device_pixel_scale), 0.f, 1.f))).sel(X,Y);
}
} else {
(vi).local_pos = local_pos;
}
vec2_scalar final_offset = (-(content_origin))+((task_rect).p0);
gl_Position = (uTransform)*(make_vec4((device_pos)+((final_offset)*((world_pos).w)), (z)*((world_pos).w), (world_pos).w));
return vi;
}
PrimitiveInfo quad_primive_info(void) {
QuadInstance_scalar qi = decode_instance();
QuadHeader_scalar qh = fetch_header((qi).prim_address_i);
Transform_scalar transform = fetch_transform((qh).transform_id);
PictureTask_scalar task = fetch_picture_task((qi).picture_task_address);
QuadPrimitive_scalar prim = fetch_primitive((qi).prim_address_f);
float z = make_float((qh).z_id);
QuadSegment_scalar seg;
if (((qi).segment_index)==(255)) {
{
(seg).rect = (prim).bounds;
(seg).uv_rect = RectWithEndpoint_scalar(make_vec2(0.f), make_vec2(0.f));
}
} else {
seg = fetch_segment((qi).prim_address_f, (qi).segment_index);
}
RectWithEndpoint_scalar local_coverage_rect = (seg).rect;
(local_coverage_rect).p0 = max((local_coverage_rect).p0, ((prim).clip).p0);
(local_coverage_rect).p1 = min((local_coverage_rect).p1, ((prim).clip).p1);
(local_coverage_rect).p1 = max((local_coverage_rect).p0, (local_coverage_rect).p1);
switch ((qi).part_index) {
case 1:
((local_coverage_rect).p1).x = (((local_coverage_rect).p0).x)+(2.f);
swgl_antiAlias(1);
break;
case 2:
((local_coverage_rect).p0).x = (((local_coverage_rect).p0).x)+(2.f);
((local_coverage_rect).p1).x = (((local_coverage_rect).p1).x)-(2.f);
((local_coverage_rect).p1).y = (((local_coverage_rect).p0).y)+(2.f);
swgl_antiAlias(2);
break;
case 3:
((local_coverage_rect).p0).x = (((local_coverage_rect).p1).x)-(2.f);
swgl_antiAlias(4);
break;
case 4:
((local_coverage_rect).p0).x = (((local_coverage_rect).p0).x)+(2.f);
((local_coverage_rect).p1).x = (((local_coverage_rect).p1).x)-(2.f);
((local_coverage_rect).p0).y = (((local_coverage_rect).p1).y)-(2.f);
swgl_antiAlias(8);
break;
case 0:
((local_coverage_rect).p0).x += edge_aa_offset(1, (qi).edge_flags);
((local_coverage_rect).p1).x -= edge_aa_offset(4, (qi).edge_flags);
((local_coverage_rect).p0).y += edge_aa_offset(2, (qi).edge_flags);
((local_coverage_rect).p1).y -= edge_aa_offset(8, (qi).edge_flags);
break;
case 5:
default:
swgl_antiAlias((qi).edge_flags);
break;
}
vec2 local_pos = mix((local_coverage_rect).p0, (local_coverage_rect).p1, aPosition);
float device_pixel_scale = (task).device_pixel_scale;
if ((((qi).quad_flags)&(4))!=(0)) {
{
device_pixel_scale = 1.f;
}
}
VertexInfo vi = write_vertex(local_pos, z, transform, (task).content_origin, (task).task_rect, device_pixel_scale, (qi).quad_flags);
v_color = (prim).color;
return PrimitiveInfo((vi).local_pos, (prim).bounds, (prim).clip, seg, (qi).edge_flags, (qi).quad_flags, (qh).pattern_input);
}
void antialiasing_vertex(PrimitiveInfo prim) {
}
Array<vec4_scalar,4> fetch_from_gpu_buffer_4f(int32_t address) {
ivec2_scalar uv = get_gpu_buffer_uv(address);
auto sGpuBufferF_uv_fetch = texelFetchPtr(sGpuBufferF, uv, 0, 3, 0, 0);
return Array<vec4_scalar,4>{{texelFetchUnchecked(sGpuBufferF, sGpuBufferF_uv_fetch, 0, 0), texelFetchUnchecked(sGpuBufferF, sGpuBufferF_uv_fetch, 1, 0), texelFetchUnchecked(sGpuBufferF, sGpuBufferF_uv_fetch, 2, 0), texelFetchUnchecked(sGpuBufferF, sGpuBufferF_uv_fetch, 3, 0)}};
}
Clip_scalar fetch_clip(int32_t index) {
Clip_scalar clip;
(clip).space = (aClipData).z;
Array<vec4_scalar,4> texels = fetch_from_gpu_buffer_4f(index);
(clip).rect = RectWithEndpoint_scalar((texels[0]).sel(X,Y), (texels[0]).sel(Z,W));
(clip).radii_top = texels[1];
(clip).radii_bottom = texels[2];
(clip).mode = (texels[3]).x;
return clip;
}
vec2_scalar inverse_radii_squared(vec2_scalar radii) {
return (1.f)/(max((radii)*(radii), 0.000001f));
}
void pattern_vertex(PrimitiveInfo prim_info) {
Clip_scalar clip = fetch_clip((aClipData).y);
Transform_scalar clip_transform = fetch_transform((aClipData).x);
vClipLocalPos = ((clip_transform).m)*(make_vec4((prim_info).local_pos, 0.f, 1.f));
if (((clip).space)==(0)) {
{
vTransformBounds = make_vec4(((clip).rect).p0, ((clip).rect).p1);
}
} else {
RectWithEndpoint xf_bounds = RectWithEndpoint(max(((clip).rect).p0, ((prim_info).local_clip_rect).p0), min(((clip).rect).p1, ((prim_info).local_clip_rect).p1));
vTransformBounds = force_scalar(make_vec4((xf_bounds).p0, (xf_bounds).p1));
}
(vClipMode).x = (clip).mode;
vec2_scalar r_tl = ((clip).radii_top).sel(X,Y);
vec2_scalar r_tr = ((clip).radii_top).sel(Z,W);
vec2_scalar r_br = ((clip).radii_bottom).sel(Z,W);
vec2_scalar r_bl = ((clip).radii_bottom).sel(X,Y);
vClipCenter_Radius_TL = make_vec4((((clip).rect).p0)+(r_tl), inverse_radii_squared(r_tl));
vClipCenter_Radius_TR = make_vec4(((((clip).rect).p1).x)-((r_tr).x), ((((clip).rect).p0).y)+((r_tr).y), inverse_radii_squared(r_tr));
vClipCenter_Radius_BR = make_vec4((((clip).rect).p1)-(r_br), inverse_radii_squared(r_br));
vClipCenter_Radius_BL = make_vec4(((((clip).rect).p0).x)+((r_bl).x), ((((clip).rect).p1).y)-((r_bl).y), inverse_radii_squared(r_bl));
vec2_scalar n_tl = -((r_tl).sel(Y,X));
vec2_scalar n_tr = make_vec2((r_tr).y, -((r_tr).x));
vec2_scalar n_br = (r_br).sel(Y,X);
vec2_scalar n_bl = make_vec2(-((r_bl).y), (r_bl).x);
vec3_scalar tl = make_vec3(n_tl, dot(n_tl, make_vec2((((clip).rect).p0).x, ((((clip).rect).p0).y)+((r_tl).y))));
vec3_scalar tr = make_vec3(n_tr, dot(n_tr, make_vec2(((((clip).rect).p1).x)-((r_tr).x), (((clip).rect).p0).y)));
vec3_scalar br = make_vec3(n_br, dot(n_br, make_vec2((((clip).rect).p1).x, ((((clip).rect).p1).y)-((r_br).y))));
vec3_scalar bl = make_vec3(n_bl, dot(n_bl, make_vec2(((((clip).rect).p0).x)+((r_bl).x), (((clip).rect).p1).y)));
vClipPlane_A = make_vec4((tl).x, (tl).y, (tl).z, (tr).x);
vClipPlane_B = make_vec4((tr).y, (tr).z, (br).x, (br).y);
vClipPlane_C = make_vec4((br).z, (bl).x, (bl).y, (bl).z);
}
ALWAYS_INLINE void main() {
PrimitiveInfo prim = quad_primive_info();
antialiasing_vertex(prim);
pattern_vertex(prim);
}
static void set_uniform_1i(VertexShaderImpl* impl, int index, int value) {
Self* self = (Self*)impl;
if (self->samplers.set_slot(index, value)) return;
switch (index) {
case 3:
assert(0); // sGpuBufferF
break;
case 4:
assert(0); // sGpuBufferI
break;
case 2:
assert(0); // sRenderTasks
break;
case 1:
assert(0); // sTransformPalette
break;
case 5:
assert(0); // uTransform
break;
}
}
static void set_uniform_4fv(VertexShaderImpl* impl, int index, const float *value) {
Self* self = (Self*)impl;
switch (index) {
case 3:
assert(0); // sGpuBufferF
break;
case 4:
assert(0); // sGpuBufferI
break;
case 2:
assert(0); // sRenderTasks
break;
case 1:
assert(0); // sTransformPalette
break;
case 5:
assert(0); // uTransform
break;
}
}
static void set_uniform_matrix4fv(VertexShaderImpl* impl, int index, const float *value) {
Self* self = (Self*)impl;
switch (index) {
case 3:
assert(0); // sGpuBufferF
break;
case 4:
assert(0); // sGpuBufferI
break;
case 2:
assert(0); // sRenderTasks
break;
case 1:
assert(0); // sTransformPalette
break;
case 5:
self->uTransform = mat4_scalar::load_from_ptr(value);
break;
}
}
static void load_attribs(VertexShaderImpl* impl, VertexAttrib *attribs, uint32_t start, int instance, int count) {Self* self = (Self*)impl;
load_attrib(self->aPosition, attribs[self->attrib_locations.aPosition], start, instance, count);
load_flat_attrib(self->aData, attribs[self->attrib_locations.aData], start, instance, count);
load_flat_attrib(self->aClipData, attribs[self->attrib_locations.aClipData], start, instance, count);
}
public:
struct InterpOutputs {
vec4_scalar vClipLocalPos;
};
private:
ALWAYS_INLINE void store_interp_outputs(char* dest_ptr, size_t stride) {
for(int n = 0; n < 4; n++) {
auto* dest = reinterpret_cast<InterpOutputs*>(dest_ptr);
dest->vClipLocalPos = get_nth(vClipLocalPos, n);
dest_ptr += stride;
}
}
static void run(VertexShaderImpl* impl, char* interps, size_t interp_stride) {
Self* self = (Self*)impl;
self->main();
self->store_interp_outputs(interps, interp_stride);
}
static void init_batch(VertexShaderImpl* impl) {
Self* self = (Self*)impl; self->bind_textures(); }
public:
ps_quad_mask_vert() {
set_uniform_1i_func = &set_uniform_1i;
set_uniform_4fv_func = &set_uniform_4fv;
set_uniform_matrix4fv_func = &set_uniform_matrix4fv;
init_batch_func = &init_batch;
load_attribs_func = &load_attribs;
run_primitive_func = &run;
}
};
struct ps_quad_mask_frag : FragmentShaderImpl, ps_quad_mask_vert {
private:
typedef ps_quad_mask_frag Self;
#define oFragColor gl_FragColor
// vec4 oFragColor;
// sampler2D sColor0;
// sampler2D sColor1;
// sampler2D sColor2;
struct RectWithSize_scalar {
vec2_scalar p0;
vec2_scalar size;
RectWithSize_scalar() = default;
RectWithSize_scalar(vec2_scalar p0, vec2_scalar size) : p0(p0), size(size){}
};
struct RectWithSize {
vec2 p0;
vec2 size;
RectWithSize() = default;
RectWithSize(vec2 p0, vec2 size) : p0(p0), size(size){}
RectWithSize(vec2_scalar p0, vec2_scalar size):p0(p0),size(size){
}
IMPLICIT RectWithSize(RectWithSize_scalar s):p0(s.p0),size(s.size){
}
friend RectWithSize if_then_else(I32 c, RectWithSize t, RectWithSize e) { return RectWithSize(
if_then_else(c, t.p0, e.p0), if_then_else(c, t.size, e.size));
}};
struct RectWithEndpoint_scalar {
vec2_scalar p0;
vec2_scalar p1;
RectWithEndpoint_scalar() = default;
RectWithEndpoint_scalar(vec2_scalar p0, vec2_scalar p1) : p0(p0), p1(p1){}
};
struct RectWithEndpoint {
vec2 p0;
vec2 p1;
RectWithEndpoint() = default;
RectWithEndpoint(vec2 p0, vec2 p1) : p0(p0), p1(p1){}
RectWithEndpoint(vec2_scalar p0, vec2_scalar p1):p0(p0),p1(p1){
}
IMPLICIT RectWithEndpoint(RectWithEndpoint_scalar s):p0(s.p0),p1(s.p1){
}
friend RectWithEndpoint if_then_else(I32 c, RectWithEndpoint t, RectWithEndpoint e) { return RectWithEndpoint(
if_then_else(c, t.p0, e.p0), if_then_else(c, t.p1, e.p1));
}};
// vec4_scalar vTransformBounds;
// sampler2D sGpuBufferF;
// isampler2D sGpuBufferI;
// vec4_scalar v_color;
// ivec4_scalar v_flags;
vec4 vClipLocalPos;
// vec4_scalar vClipCenter_Radius_TL;
// vec4_scalar vClipCenter_Radius_TR;
// vec4_scalar vClipCenter_Radius_BR;
// vec4_scalar vClipCenter_Radius_BL;
// vec4_scalar vClipPlane_A;
// vec4_scalar vClipPlane_B;
// vec4_scalar vClipPlane_C;
// vec2_scalar vClipMode;
float antialiasing_fragment() {
float alpha = 1.f;
return alpha;
}
float compute_aa_range(vec2 position) {
return recip((fwidth(position)).x);
}
Float distance_to_ellipse_approx(vec2 p, vec2 inv_radii_sq, float scale) {
vec2 p_r = (p)*(inv_radii_sq);
Float g = (dot(p, p_r))-(scale);
vec2 dG = ((1.f)+(scale))*(p_r);
return (g)*(inversesqrt(dot(dG, dG)));
}
vec2 signed_distance_rect_xy(vec2 pos, vec2_scalar p0, vec2_scalar p1) {
return max((p0)-(pos), (pos)-(p1));
}
Float signed_distance_rect(vec2 pos, vec2_scalar p0, vec2_scalar p1) {
vec2 d = signed_distance_rect_xy(pos, p0, p1);
return max((d).x, (d).y);
}
Float distance_to_rounded_rect(vec2 pos, vec3_scalar plane_tl, vec4 center_radius_tl, vec3_scalar plane_tr, vec4 center_radius_tr, vec3_scalar plane_br, vec4 center_radius_br, vec3_scalar plane_bl, vec4 center_radius_bl, vec4_scalar rect_bounds) {
vec4 corner = make_vec4(make_vec2(0.000001f), make_vec2(1.f));
(center_radius_tl).lsel(X,Y) = ((center_radius_tl).sel(X,Y))-(pos);
(center_radius_tr).lsel(X,Y) = (((center_radius_tr).sel(X,Y))-(pos))*(make_vec2(-(1.f), 1.f));
(center_radius_br).lsel(X,Y) = (pos)-((center_radius_br).sel(X,Y));
(center_radius_bl).lsel(X,Y) = (((center_radius_bl).sel(X,Y))-(pos))*(make_vec2(1.f, -(1.f)));
auto _c5_ = (dot(pos, (plane_tl).sel(X,Y)))>((plane_tl).z);
{
corner = if_then_else(_c5_,center_radius_tl,corner);
}
auto _c6_ = (dot(pos, (plane_tr).sel(X,Y)))>((plane_tr).z);
{
corner = if_then_else(_c6_,center_radius_tr,corner);
}
auto _c7_ = (dot(pos, (plane_br).sel(X,Y)))>((plane_br).z);
{
corner = if_then_else(_c7_,center_radius_br,corner);
}
auto _c8_ = (dot(pos, (plane_bl).sel(X,Y)))>((plane_bl).z);
{
corner = if_then_else(_c8_,center_radius_bl,corner);
}
return max(distance_to_ellipse_approx((corner).sel(X,Y), (corner).sel(Z,W), 1.f), signed_distance_rect(pos, (rect_bounds).sel(X,Y), (rect_bounds).sel(Z,W)));
}
Float distance_aa(float aa_range, Float signed_distance) {
Float dist = (signed_distance)*(aa_range);
return clamp((0.5f)-(dist), 0.f, 1.f);
}
vec4 pattern_fragment(vec4_scalar _base_color) {
vec2 clip_local_pos = ((vClipLocalPos).sel(X,Y))/((vClipLocalPos).w);
float aa_range = compute_aa_range(clip_local_pos);
vec3_scalar plane_tl = make_vec3((vClipPlane_A).x, (vClipPlane_A).y, (vClipPlane_A).z);
vec3_scalar plane_tr = make_vec3((vClipPlane_A).w, (vClipPlane_B).x, (vClipPlane_B).y);
vec3_scalar plane_br = make_vec3((vClipPlane_B).z, (vClipPlane_B).w, (vClipPlane_C).x);
vec3_scalar plane_bl = make_vec3((vClipPlane_C).y, (vClipPlane_C).z, (vClipPlane_C).w);
Float dist = distance_to_rounded_rect(clip_local_pos, plane_tl, vClipCenter_Radius_TL, plane_tr, vClipCenter_Radius_TR, plane_br, vClipCenter_Radius_BR, plane_bl, vClipCenter_Radius_BL, vTransformBounds);
Float alpha = distance_aa(aa_range, dist);
Float final_alpha = mix(alpha, (1.f)-(alpha), (vClipMode).x);
return make_vec4(final_alpha);
}
ALWAYS_INLINE void main() {
vec4_scalar base_color = v_color;
base_color *= antialiasing_fragment();
oFragColor = pattern_fragment(base_color);
}
typedef ps_quad_mask_vert::InterpOutputs InterpInputs;
InterpInputs interp_step;
struct InterpPerspective {
vec4 vClipLocalPos;
};
InterpPerspective interp_perspective;
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_;
self->vClipLocalPos = init_interp(init->vClipLocalPos, step->vClipLocalPos);
self->interp_step.vClipLocalPos = step->vClipLocalPos * 4.0f;
}
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_;
Float w = 1.0f / self->gl_FragCoord.w;
self->interp_perspective.vClipLocalPos = init_interp(init->vClipLocalPos, step->vClipLocalPos);
self->vClipLocalPos = self->interp_perspective.vClipLocalPos * w;
self->interp_step.vClipLocalPos = step->vClipLocalPos * 4.0f;
}
ALWAYS_INLINE void step_interp_inputs(int steps = 4) {
float chunks = steps * 0.25f;
vClipLocalPos += interp_step.vClipLocalPos * chunks;
}
ALWAYS_INLINE void step_perspective_inputs(int steps = 4) {
step_perspective(steps);
float chunks = steps * 0.25f;
Float w = 1.0f / gl_FragCoord.w;
interp_perspective.vClipLocalPos += interp_step.vClipLocalPos * chunks;
vClipLocalPos = w * interp_perspective.vClipLocalPos;
}
static void run(FragmentShaderImpl* impl) {
Self* self = (Self*)impl;
self->main();
self->step_interp_inputs();
}
static void skip(FragmentShaderImpl* impl, int steps) {
Self* self = (Self*)impl;
self->step_interp_inputs(steps);
}
static void run_perspective(FragmentShaderImpl* impl) {
Self* self = (Self*)impl;
self->main();
self->step_perspective_inputs();
}
static void skip_perspective(FragmentShaderImpl* impl, int steps) {
Self* self = (Self*)impl;
self->step_perspective_inputs(steps);
}
public:
ps_quad_mask_frag() {
init_span_func = &read_interp_inputs;
run_func = &run;
skip_func = &skip;
enable_perspective();
init_span_w_func = &read_perspective_inputs;
run_w_func = &run_perspective;
skip_w_func = &skip_perspective;
}
};
struct ps_quad_mask_program : ProgramImpl, ps_quad_mask_frag {
int get_uniform(const char *name) const override {
if (strcmp("sGpuBufferF", name) == 0) { return 3; }
if (strcmp("sGpuBufferI", name) == 0) { return 4; }
if (strcmp("sRenderTasks", name) == 0) { return 2; }
if (strcmp("sTransformPalette", name) == 0) { return 1; }
if (strcmp("uTransform", name) == 0) { return 5; }
return -1;
}
void bind_attrib(const char* name, int index) override {
attrib_locations.bind_loc(name, index);
}
int get_attrib(const char* name) const override {
return attrib_locations.get_loc(name);
}
size_t interpolants_size() const override { return sizeof(InterpOutputs); }
VertexShaderImpl* get_vertex_shader() override {
return this;
}
FragmentShaderImpl* get_fragment_shader() override {
return this;
}
const char* get_name() const override { return "ps_quad_mask"; }
static ProgramImpl* loader() { return new ps_quad_mask_program; }
};