Copy as Markdown

Other Tools

struct composite_TEXTURE_2D_YUV_common {
struct Samplers {
sampler2D_impl sColor0_impl;
int sColor0_slot;
sampler2D_impl sColor1_impl;
int sColor1_slot;
sampler2D_impl sColor2_impl;
int sColor2_slot;
bool set_slot(int index, int value) {
switch (index) {
case 1:
sColor0_slot = value;
return true;
case 2:
sColor1_slot = value;
return true;
case 3:
sColor2_slot = value;
return true;
}
return false;
}
} samplers;
struct AttribLocations {
int aPosition = NULL_ATTRIB;
int aLocalRect = NULL_ATTRIB;
int aDeviceClipRect = NULL_ATTRIB;
int aParams = NULL_ATTRIB;
int aTransform = NULL_ATTRIB;
int aUvRect0 = NULL_ATTRIB;
int aUvRect1 = NULL_ATTRIB;
int aUvRect2 = NULL_ATTRIB;
void bind_loc(const char* name, int index) {
if (strcmp("aPosition", name) == 0) { aPosition = index; return; }
if (strcmp("aLocalRect", name) == 0) { aLocalRect = index; return; }
if (strcmp("aDeviceClipRect", name) == 0) { aDeviceClipRect = index; return; }
if (strcmp("aParams", name) == 0) { aParams = index; return; }
if (strcmp("aTransform", name) == 0) { aTransform = index; return; }
if (strcmp("aUvRect0", name) == 0) { aUvRect0 = index; return; }
if (strcmp("aUvRect1", name) == 0) { aUvRect1 = index; return; }
if (strcmp("aUvRect2", name) == 0) { aUvRect2 = index; return; }
}
int get_loc(const char* name) const {
if (strcmp("aPosition", name) == 0) { return aPosition != NULL_ATTRIB ? aPosition : -1; }
if (strcmp("aLocalRect", name) == 0) { return aLocalRect != NULL_ATTRIB ? aLocalRect : -1; }
if (strcmp("aDeviceClipRect", name) == 0) { return aDeviceClipRect != NULL_ATTRIB ? aDeviceClipRect : -1; }
if (strcmp("aParams", name) == 0) { return aParams != NULL_ATTRIB ? aParams : -1; }
if (strcmp("aTransform", name) == 0) { return aTransform != NULL_ATTRIB ? aTransform : -1; }
if (strcmp("aUvRect0", name) == 0) { return aUvRect0 != NULL_ATTRIB ? aUvRect0 : -1; }
if (strcmp("aUvRect1", name) == 0) { return aUvRect1 != NULL_ATTRIB ? aUvRect1 : -1; }
if (strcmp("aUvRect2", name) == 0) { return aUvRect2 != NULL_ATTRIB ? aUvRect2 : -1; }
return -1;
}
} attrib_locations;
vec3_scalar vYcbcrBias;
mat3_scalar vRgbFromDebiasedYcbcr;
ivec2_scalar vYuvFormat;
int32_t vRescaleFactor;
vec4_scalar vUVBounds_y;
vec4_scalar vUVBounds_u;
vec4_scalar vUVBounds_v;
sampler2D sColor0;
sampler2D sColor1;
sampler2D sColor2;
mat4_scalar uTransform;
void bind_textures() {
sColor0 = lookup_sampler(&samplers.sColor0_impl, samplers.sColor0_slot);
sColor1 = lookup_sampler(&samplers.sColor1_impl, samplers.sColor1_slot);
sColor2 = lookup_sampler(&samplers.sColor2_impl, samplers.sColor2_slot);
}
};
struct composite_TEXTURE_2D_YUV_vert : VertexShaderImpl, composite_TEXTURE_2D_YUV_common {
private:
typedef composite_TEXTURE_2D_YUV_vert Self;
// mat4_scalar uTransform;
vec2 aPosition;
// sampler2D sColor0;
// sampler2D sColor1;
// sampler2D sColor2;
mat3_scalar static constexpr RgbFromYuv_Rec601 = make_mat3(1.f, 1.f, 1.f, 0.f, -(0.17207f), 0.886f, 0.701f, -(0.35707f), 0.f);
mat3_scalar static constexpr RgbFromYuv_Rec709 = make_mat3(1.f, 1.f, 1.f, 0.f, -(0.09366f), 0.9278f, 0.7874f, -(0.23406f), 0.f);
mat3_scalar static constexpr RgbFromYuv_Rec2020 = make_mat3(1.f, 1.f, 1.f, 0.f, -(0.08228f), 0.9407f, 0.7373f, -(0.28568f), 0.f);
mat3_scalar static constexpr RgbFromYuv_GbrIdentity = make_mat3(0.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 0.f);
struct YuvPrimitive_scalar {
int32_t channel_bit_depth;
int32_t color_space;
int32_t yuv_format;
YuvPrimitive_scalar() = default;
YuvPrimitive_scalar(int32_t channel_bit_depth, int32_t color_space, int32_t yuv_format) : channel_bit_depth(channel_bit_depth), color_space(color_space), yuv_format(yuv_format){}
};
struct YuvPrimitive {
I32 channel_bit_depth;
I32 color_space;
I32 yuv_format;
YuvPrimitive() = default;
YuvPrimitive(I32 channel_bit_depth, I32 color_space, I32 yuv_format) : channel_bit_depth(channel_bit_depth), color_space(color_space), yuv_format(yuv_format){}
YuvPrimitive(int32_t channel_bit_depth, int32_t color_space, int32_t yuv_format):channel_bit_depth(channel_bit_depth),color_space(color_space),yuv_format(yuv_format){
}
IMPLICIT YuvPrimitive(YuvPrimitive_scalar s):channel_bit_depth(s.channel_bit_depth),color_space(s.color_space),yuv_format(s.yuv_format){
}
friend YuvPrimitive if_then_else(I32 c, YuvPrimitive t, YuvPrimitive e) { return YuvPrimitive(
if_then_else(c, t.channel_bit_depth, e.channel_bit_depth), if_then_else(c, t.color_space, e.color_space), if_then_else(c, t.yuv_format, e.yuv_format));
}};
struct YuvColorSamplingInfo_scalar {
mat3_scalar rgb_from_yuv;
vec4_scalar packed_zero_one_vals;
YuvColorSamplingInfo_scalar() = default;
YuvColorSamplingInfo_scalar(mat3_scalar rgb_from_yuv, vec4_scalar packed_zero_one_vals) : rgb_from_yuv(rgb_from_yuv), packed_zero_one_vals(packed_zero_one_vals){}
};
struct YuvColorSamplingInfo {
mat3 rgb_from_yuv;
vec4 packed_zero_one_vals;
YuvColorSamplingInfo() = default;
YuvColorSamplingInfo(mat3 rgb_from_yuv, vec4 packed_zero_one_vals) : rgb_from_yuv(rgb_from_yuv), packed_zero_one_vals(packed_zero_one_vals){}
YuvColorSamplingInfo(mat3_scalar rgb_from_yuv, vec4_scalar packed_zero_one_vals):rgb_from_yuv(rgb_from_yuv),packed_zero_one_vals(packed_zero_one_vals){
}
IMPLICIT YuvColorSamplingInfo(YuvColorSamplingInfo_scalar s):rgb_from_yuv(s.rgb_from_yuv),packed_zero_one_vals(s.packed_zero_one_vals){
}
friend YuvColorSamplingInfo if_then_else(I32 c, YuvColorSamplingInfo t, YuvColorSamplingInfo e) { return YuvColorSamplingInfo(
if_then_else(c, t.rgb_from_yuv, e.rgb_from_yuv), if_then_else(c, t.packed_zero_one_vals, e.packed_zero_one_vals));
}};
struct YuvColorMatrixInfo_scalar {
vec3_scalar ycbcr_bias;
mat3_scalar rgb_from_debiased_ycbrc;
YuvColorMatrixInfo_scalar() = default;
YuvColorMatrixInfo_scalar(vec3_scalar ycbcr_bias, mat3_scalar rgb_from_debiased_ycbrc) : ycbcr_bias(ycbcr_bias), rgb_from_debiased_ycbrc(rgb_from_debiased_ycbrc){}
};
struct YuvColorMatrixInfo {
vec3 ycbcr_bias;
mat3 rgb_from_debiased_ycbrc;
YuvColorMatrixInfo() = default;
YuvColorMatrixInfo(vec3 ycbcr_bias, mat3 rgb_from_debiased_ycbrc) : ycbcr_bias(ycbcr_bias), rgb_from_debiased_ycbrc(rgb_from_debiased_ycbrc){}
YuvColorMatrixInfo(vec3_scalar ycbcr_bias, mat3_scalar rgb_from_debiased_ycbrc):ycbcr_bias(ycbcr_bias),rgb_from_debiased_ycbrc(rgb_from_debiased_ycbrc){
}
IMPLICIT YuvColorMatrixInfo(YuvColorMatrixInfo_scalar s):ycbcr_bias(s.ycbcr_bias),rgb_from_debiased_ycbrc(s.rgb_from_debiased_ycbrc){
}
friend YuvColorMatrixInfo if_then_else(I32 c, YuvColorMatrixInfo t, YuvColorMatrixInfo e) { return YuvColorMatrixInfo(
if_then_else(c, t.ycbcr_bias, e.ycbcr_bias), if_then_else(c, t.rgb_from_debiased_ycbrc, e.rgb_from_debiased_ycbrc));
}};
// vec3_scalar vYcbcrBias;
// mat3_scalar vRgbFromDebiasedYcbcr;
// ivec2_scalar vYuvFormat;
// int32_t vRescaleFactor;
vec2 vUV_y;
vec2 vUV_u;
vec2 vUV_v;
// vec4_scalar vUVBounds_y;
// vec4_scalar vUVBounds_u;
// vec4_scalar vUVBounds_v;
vec4_scalar aLocalRect;
vec4_scalar aDeviceClipRect;
vec4_scalar aColor;
vec4_scalar aParams;
vec4_scalar aTransform;
vec4_scalar aUvRect0;
vec4_scalar aUvRect1;
vec4_scalar aUvRect2;
vec2_scalar apply_transform(vec2_scalar p, vec4_scalar transform) {
return ((p)*((transform).sel(X,Y)))+((transform).sel(Z,W));
}
YuvPrimitive_scalar fetch_yuv_primitive() {
int32_t color_space = make_int((aParams).y);
int32_t yuv_format = make_int((aParams).z);
int32_t channel_bit_depth = make_int((aParams).w);
return YuvPrimitive_scalar(channel_bit_depth, color_space, yuv_format);
}
vec4_scalar yuv_channel_zero_one_narrow_range(int32_t bit_depth, float channel_max) {
ivec4_scalar zero_one_ints = (make_ivec4(16, 128, 235, 240))<<((bit_depth)-(8));
return (make_vec4(zero_one_ints))/(channel_max);
}
vec4_scalar yuv_channel_zero_one_identity(int32_t bit_depth, float channel_max) {
float all_ones_normalized = (make_float(((1)<<(bit_depth))-(1)))/(channel_max);
return make_vec4(0.f, 0.f, all_ones_normalized, all_ones_normalized);
}
vec4_scalar yuv_channel_zero_one_full_range(int32_t bit_depth, float channel_max) {
vec4_scalar narrow = yuv_channel_zero_one_narrow_range(bit_depth, channel_max);
vec4_scalar identity = yuv_channel_zero_one_identity(bit_depth, channel_max);
return make_vec4(0.f, (narrow).y, (identity).z, (identity).w);
}
YuvColorSamplingInfo_scalar get_yuv_color_info(YuvPrimitive_scalar prim) {
float channel_max = 255.f;
if (((prim).channel_bit_depth)>(8)) {
{
if (((prim).yuv_format)==(1)) {
{
channel_max = make_float(((1)<<((prim).channel_bit_depth))-(1));
}
} else {
channel_max = 65535.f;
}
}
}
if (((prim).color_space)==(0)) {
{
return YuvColorSamplingInfo_scalar(RgbFromYuv_Rec601, yuv_channel_zero_one_narrow_range((prim).channel_bit_depth, channel_max));
}
} else if (((prim).color_space)==(1)) {
{
return YuvColorSamplingInfo_scalar(RgbFromYuv_Rec601, yuv_channel_zero_one_full_range((prim).channel_bit_depth, channel_max));
}
} else if (((prim).color_space)==(2)) {
{
return YuvColorSamplingInfo_scalar(RgbFromYuv_Rec709, yuv_channel_zero_one_narrow_range((prim).channel_bit_depth, channel_max));
}
} else if (((prim).color_space)==(3)) {
{
return YuvColorSamplingInfo_scalar(RgbFromYuv_Rec709, yuv_channel_zero_one_full_range((prim).channel_bit_depth, channel_max));
}
} else if (((prim).color_space)==(4)) {
{
return YuvColorSamplingInfo_scalar(RgbFromYuv_Rec2020, yuv_channel_zero_one_narrow_range((prim).channel_bit_depth, channel_max));
}
} else if (((prim).color_space)==(5)) {
{
return YuvColorSamplingInfo_scalar(RgbFromYuv_Rec2020, yuv_channel_zero_one_full_range((prim).channel_bit_depth, channel_max));
}
} else {
return YuvColorSamplingInfo_scalar(RgbFromYuv_GbrIdentity, yuv_channel_zero_one_identity((prim).channel_bit_depth, channel_max));
}
}
YuvColorMatrixInfo_scalar get_rgb_from_ycbcr_info(YuvPrimitive_scalar prim) {
YuvColorSamplingInfo_scalar info = get_yuv_color_info(prim);
vec2_scalar zero = ((info).packed_zero_one_vals).sel(X,Y);
vec2_scalar one = ((info).packed_zero_one_vals).sel(Z,W);
vec2_scalar scale = (1.f)/((one)-(zero));
YuvColorMatrixInfo_scalar mat_info;
(mat_info).ycbcr_bias = (zero).sel(X,Y,Y);
mat3_scalar yuv_from_debiased_ycbcr = make_mat3((scale).x, 0.f, 0.f, 0.f, (scale).y, 0.f, 0.f, 0.f, (scale).y);
(mat_info).rgb_from_debiased_ycbrc = ((info).rgb_from_yuv)*(yuv_from_debiased_ycbcr);
return mat_info;
}
void write_uv_rect(vec2_scalar uv0, vec2_scalar uv1, vec2 f, vec2_scalar texture_size, vec2& uv, vec4_scalar& uv_bounds) {
uv = mix(uv0, uv1, f);
uv_bounds = make_vec4((uv0)+(make_vec2(0.5f)), (uv1)-(make_vec2(0.5f)));
uv /= texture_size;
uv_bounds /= (texture_size).sel(X,Y,X,Y);
}
ALWAYS_INLINE void main(void) {
vec2_scalar world_p0 = apply_transform((aLocalRect).sel(X,Y), aTransform);
vec2_scalar world_p1 = apply_transform((aLocalRect).sel(Z,W), aTransform);
vec2 world_pos = mix(world_p0, world_p1, (aPosition).sel(X,Y));
vec2 clipped_world_pos = clamp(world_pos, (aDeviceClipRect).sel(X,Y), (aDeviceClipRect).sel(Z,W));
vec2 uv = ((clipped_world_pos)-(world_p0))/((world_p1)-(world_p0));
YuvPrimitive_scalar prim = fetch_yuv_primitive();
vRescaleFactor = 0;
if ((((prim).channel_bit_depth)>(8))&&(((prim).yuv_format)!=(1))) {
{
vRescaleFactor = (16)-((prim).channel_bit_depth);
}
}
YuvColorMatrixInfo_scalar mat_info = get_rgb_from_ycbcr_info(prim);
vYcbcrBias = (mat_info).ycbcr_bias;
vRgbFromDebiasedYcbcr = (mat_info).rgb_from_debiased_ycbrc;
(vYuvFormat).x = (prim).yuv_format;
write_uv_rect((aUvRect0).sel(X,Y), (aUvRect0).sel(Z,W), uv, make_vec2((textureSize(sColor0, 0)).sel(X,Y)), vUV_y, vUVBounds_y);
write_uv_rect((aUvRect1).sel(X,Y), (aUvRect1).sel(Z,W), uv, make_vec2((textureSize(sColor1, 0)).sel(X,Y)), vUV_u, vUVBounds_u);
write_uv_rect((aUvRect2).sel(X,Y), (aUvRect2).sel(Z,W), uv, make_vec2((textureSize(sColor2, 0)).sel(X,Y)), vUV_v, vUVBounds_v);
gl_Position = (uTransform)*(make_vec4(clipped_world_pos, 0.f, 1.f));
}
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 1:
assert(0); // sColor0
break;
case 2:
assert(0); // sColor1
break;
case 3:
assert(0); // sColor2
break;
case 4:
assert(0); // uTransform
break;
}
}
static void set_uniform_4fv(VertexShaderImpl* impl, int index, const float *value) {
Self* self = (Self*)impl;
switch (index) {
case 1:
assert(0); // sColor0
break;
case 2:
assert(0); // sColor1
break;
case 3:
assert(0); // sColor2
break;
case 4:
assert(0); // uTransform
break;
}
}
static void set_uniform_matrix4fv(VertexShaderImpl* impl, int index, const float *value) {
Self* self = (Self*)impl;
switch (index) {
case 1:
assert(0); // sColor0
break;
case 2:
assert(0); // sColor1
break;
case 3:
assert(0); // sColor2
break;
case 4:
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->aLocalRect, attribs[self->attrib_locations.aLocalRect], start, instance, count);
load_flat_attrib(self->aDeviceClipRect, attribs[self->attrib_locations.aDeviceClipRect], start, instance, count);
load_flat_attrib(self->aParams, attribs[self->attrib_locations.aParams], start, instance, count);
load_flat_attrib(self->aTransform, attribs[self->attrib_locations.aTransform], start, instance, count);
load_flat_attrib(self->aUvRect0, attribs[self->attrib_locations.aUvRect0], start, instance, count);
load_flat_attrib(self->aUvRect1, attribs[self->attrib_locations.aUvRect1], start, instance, count);
load_flat_attrib(self->aUvRect2, attribs[self->attrib_locations.aUvRect2], start, instance, count);
}
public:
struct InterpOutputs {
vec2_scalar vUV_y;
vec2_scalar vUV_u;
vec2_scalar vUV_v;
};
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->vUV_y = get_nth(vUV_y, n);
dest->vUV_u = get_nth(vUV_u, n);
dest->vUV_v = get_nth(vUV_v, 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:
composite_TEXTURE_2D_YUV_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;
}
};
mat3_scalar constexpr composite_TEXTURE_2D_YUV_vert::RgbFromYuv_Rec601;
mat3_scalar constexpr composite_TEXTURE_2D_YUV_vert::RgbFromYuv_Rec709;
mat3_scalar constexpr composite_TEXTURE_2D_YUV_vert::RgbFromYuv_Rec2020;
mat3_scalar constexpr composite_TEXTURE_2D_YUV_vert::RgbFromYuv_GbrIdentity;
struct composite_TEXTURE_2D_YUV_frag : FragmentShaderImpl, composite_TEXTURE_2D_YUV_vert {
private:
typedef composite_TEXTURE_2D_YUV_frag Self;
#define oFragColor gl_FragColor
// vec4 oFragColor;
// sampler2D sColor0;
// sampler2D sColor1;
// sampler2D sColor2;
// vec3_scalar vYcbcrBias;
// mat3_scalar vRgbFromDebiasedYcbcr;
// ivec2_scalar vYuvFormat;
// int32_t vRescaleFactor;
vec2 vUV_y;
vec2 vUV_u;
vec2 vUV_v;
// vec4_scalar vUVBounds_y;
// vec4_scalar vUVBounds_u;
// vec4_scalar vUVBounds_v;
vec4 sample_yuv(int32_t format, vec3_scalar ycbcr_bias, mat3_scalar rgb_from_debiased_ycbrc, vec2 in_uv_y, vec2 in_uv_u, vec2 in_uv_v, vec4_scalar uv_bounds_y, vec4_scalar uv_bounds_u, vec4_scalar uv_bounds_v) {
vec3 ycbcr_sample;
switch (format) {
case 2:
{
vec2 uv_y = clamp(in_uv_y, (uv_bounds_y).sel(X,Y), (uv_bounds_y).sel(Z,W));
vec2 uv_u = clamp(in_uv_u, (uv_bounds_u).sel(X,Y), (uv_bounds_u).sel(Z,W));
vec2 uv_v = clamp(in_uv_v, (uv_bounds_v).sel(X,Y), (uv_bounds_v).sel(Z,W));
(ycbcr_sample).x = (texture(sColor0, (uv_y).sel(X,Y))).x;
(ycbcr_sample).y = (texture(sColor1, (uv_u).sel(X,Y))).x;
(ycbcr_sample).z = (texture(sColor2, (uv_v).sel(X,Y))).x;
}
break;
case 0:
case 1:
{
vec2 uv_y = clamp(in_uv_y, (uv_bounds_y).sel(X,Y), (uv_bounds_y).sel(Z,W));
vec2 uv_uv = clamp(in_uv_u, (uv_bounds_u).sel(X,Y), (uv_bounds_u).sel(Z,W));
(ycbcr_sample).x = (texture(sColor0, (uv_y).sel(X,Y))).x;
(ycbcr_sample).lsel(Y,Z) = (texture(sColor1, (uv_uv).sel(X,Y))).sel(R,G);
}
break;
case 3:
{
vec2 uv_y = clamp(in_uv_y, (uv_bounds_y).sel(X,Y), (uv_bounds_y).sel(Z,W));
ycbcr_sample = (texture(sColor0, (uv_y).sel(X,Y))).sel(G,B,R);
}
break;
default:
ycbcr_sample = make_vec3(0.f);
break;
}
vec3 rgb = (rgb_from_debiased_ycbrc)*((ycbcr_sample)-(ycbcr_bias));
return make_vec4(rgb, 1.f);
}
void write_output(vec4 color) {
oFragColor = color;
}
ALWAYS_INLINE void main(void) {
vec4 color = sample_yuv((vYuvFormat).x, vYcbcrBias, vRgbFromDebiasedYcbcr, vUV_y, vUV_u, vUV_v, vUVBounds_y, vUVBounds_u, vUVBounds_v);
write_output(color);
}
void swgl_drawSpanRGBA8() {
if (((vYuvFormat).x)==(2)) {
{
swgl_commitTextureLinearYUV(sColor0, vUV_y, vUVBounds_y, sColor1, vUV_u, vUVBounds_u, sColor2, vUV_v, vUVBounds_v, vYcbcrBias, vRgbFromDebiasedYcbcr, vRescaleFactor);
}
} else if ((((vYuvFormat).x)==(0))||(((vYuvFormat).x)==(1))) {
{
swgl_commitTextureLinearYUV(sColor0, vUV_y, vUVBounds_y, sColor1, vUV_u, vUVBounds_u, vYcbcrBias, vRgbFromDebiasedYcbcr, vRescaleFactor);
}
} else if (((vYuvFormat).x)==(3)) {
{
swgl_commitTextureLinearYUV(sColor0, vUV_y, vUVBounds_y, vYcbcrBias, vRgbFromDebiasedYcbcr, vRescaleFactor);
}
}
}
typedef composite_TEXTURE_2D_YUV_vert::InterpOutputs InterpInputs;
InterpInputs interp_step;
struct InterpPerspective {
vec2 vUV_y;
vec2 vUV_u;
vec2 vUV_v;
};
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->vUV_y = init_interp(init->vUV_y, step->vUV_y);
self->interp_step.vUV_y = step->vUV_y * 4.0f;
self->vUV_u = init_interp(init->vUV_u, step->vUV_u);
self->interp_step.vUV_u = step->vUV_u * 4.0f;
self->vUV_v = init_interp(init->vUV_v, step->vUV_v);
self->interp_step.vUV_v = step->vUV_v * 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.vUV_y = init_interp(init->vUV_y, step->vUV_y);
self->vUV_y = self->interp_perspective.vUV_y * w;
self->interp_step.vUV_y = step->vUV_y * 4.0f;
self->interp_perspective.vUV_u = init_interp(init->vUV_u, step->vUV_u);
self->vUV_u = self->interp_perspective.vUV_u * w;
self->interp_step.vUV_u = step->vUV_u * 4.0f;
self->interp_perspective.vUV_v = init_interp(init->vUV_v, step->vUV_v);
self->vUV_v = self->interp_perspective.vUV_v * w;
self->interp_step.vUV_v = step->vUV_v * 4.0f;
}
ALWAYS_INLINE void step_interp_inputs(int steps = 4) {
float chunks = steps * 0.25f;
vUV_y += interp_step.vUV_y * chunks;
vUV_u += interp_step.vUV_u * chunks;
vUV_v += interp_step.vUV_v * 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.vUV_y += interp_step.vUV_y * chunks;
vUV_y = w * interp_perspective.vUV_y;
interp_perspective.vUV_u += interp_step.vUV_u * chunks;
vUV_u = w * interp_perspective.vUV_u;
interp_perspective.vUV_v += interp_step.vUV_v * chunks;
vUV_v = w * interp_perspective.vUV_v;
}
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);
}
static int draw_span_RGBA8(FragmentShaderImpl* impl) {
Self* self = (Self*)impl; DISPATCH_DRAW_SPAN(self, RGBA8); }
public:
composite_TEXTURE_2D_YUV_frag() {
init_span_func = &read_interp_inputs;
run_func = &run;
skip_func = &skip;
draw_span_RGBA8_func = &draw_span_RGBA8;
enable_perspective();
init_span_w_func = &read_perspective_inputs;
run_w_func = &run_perspective;
skip_w_func = &skip_perspective;
}
};
struct composite_TEXTURE_2D_YUV_program : ProgramImpl, composite_TEXTURE_2D_YUV_frag {
int get_uniform(const char *name) const override {
if (strcmp("sColor0", name) == 0) { return 1; }
if (strcmp("sColor1", name) == 0) { return 2; }
if (strcmp("sColor2", name) == 0) { return 3; }
if (strcmp("uTransform", name) == 0) { return 4; }
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 "composite_TEXTURE_2D_YUV"; }
static ProgramImpl* loader() { return new composite_TEXTURE_2D_YUV_program; }
};