Split debayer fragment between packed and unpacked, fixing preview for unpacked 10bit bayer formats

This commit is contained in:
Kristian Vos
2024-06-29 22:24:17 +02:00
committed by Martijn Braam
parent db188f2db7
commit 32f168b6d8
4 changed files with 103 additions and 34 deletions

View File

@@ -6,49 +6,22 @@ uniform sampler2D texture;
uniform mat3 color_matrix;
uniform float inv_gamma;
uniform float blacklevel;
#ifdef BITS_10
uniform float row_length;
uniform float padding_ratio;
#endif
varying vec2 top_left_uv;
varying vec2 top_right_uv;
varying vec2 bottom_left_uv;
varying vec2 bottom_right_uv;
#ifdef BITS_10
vec2
skip_5th_pixel(vec2 uv)
{
vec2 new_uv = uv;
new_uv.x *= 0.8;
new_uv.x += floor(uv.x * row_length / 5.0) / row_length;
// Crop out padding
new_uv.x *= padding_ratio;
return new_uv;
}
#endif
void
main()
{
// Note the coordinates for texture samples need to be a varying, as the
// Mali-400 has this as a fast path allowing 32-bit floats. Otherwise
// they end up as 16-bit floats and that's not accurate enough.
#ifdef BITS_10
vec4 samples = vec4(texture2D(texture, skip_5th_pixel(top_left_uv)).r,
texture2D(texture, skip_5th_pixel(top_right_uv)).r,
texture2D(texture, skip_5th_pixel(bottom_left_uv)).r,
texture2D(texture, skip_5th_pixel(bottom_right_uv)).r);
#else
vec4 samples = vec4(texture2D(texture, top_left_uv).r,
texture2D(texture, top_right_uv).r,
texture2D(texture, bottom_left_uv).r,
texture2D(texture, bottom_right_uv).r);
#endif
#if defined(CFA_BGGR)
vec3 color = vec3(samples.w, (samples.y + samples.z) / 2.0, samples.x);

59
data/debayer_packed.frag Normal file
View File

@@ -0,0 +1,59 @@
// This file should work with 10bit raw bayer packed formats. It is unlikely to work with 12bit or 14bit formats without a few changes.
#ifdef GL_ES
precision highp float;
#endif
uniform sampler2D texture;
uniform mat3 color_matrix;
uniform float inv_gamma;
uniform float blacklevel;
uniform float row_length;
uniform float padding_ratio;
varying vec2 top_left_uv;
varying vec2 top_right_uv;
varying vec2 bottom_left_uv;
varying vec2 bottom_right_uv;
vec2
skip_5th_pixel(vec2 uv)
{
vec2 new_uv = uv;
new_uv.x *= 0.8;
new_uv.x += floor(uv.x * row_length / 5.0) / row_length;
// Crop out padding
new_uv.x *= padding_ratio;
return new_uv;
}
void
main()
{
// Note the coordinates for texture samples need to be a varying, as the
// Mali-400 has this as a fast path allowing 32-bit floats. Otherwise
// they end up as 16-bit floats and that's not accurate enough.
vec4 samples = vec4(texture2D(texture, skip_5th_pixel(top_left_uv)).r,
texture2D(texture, skip_5th_pixel(top_right_uv)).r,
texture2D(texture, skip_5th_pixel(bottom_left_uv)).r,
texture2D(texture, skip_5th_pixel(bottom_right_uv)).r);
#if defined(CFA_BGGR)
vec3 color = vec3(samples.w, (samples.y + samples.z) / 2.0, samples.x);
#elif defined(CFA_GBRG)
vec3 color = vec3(samples.z, (samples.x + samples.w) / 2.0, samples.y);
#elif defined(CFA_GRBG)
vec3 color = vec3(samples.y, (samples.x + samples.w) / 2.0, samples.z);
#else
vec3 color = vec3(samples.x, (samples.y + samples.z) / 2.0, samples.w);
#endif
color -= blacklevel;
color *= color_matrix;
vec3 gamma_color = pow(color, vec3(inv_gamma));
gl_FragColor = vec4(gamma_color, 1);
}

View File

@@ -24,10 +24,6 @@ gles2_debayer_new(int format)
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
case V4L2_PIX_FMT_SBGGR10P:
case V4L2_PIX_FMT_SGBRG10P:
case V4L2_PIX_FMT_SGRBG10P:
case V4L2_PIX_FMT_SRGGB10P:
case V4L2_PIX_FMT_SBGGR10:
case V4L2_PIX_FMT_SGBRG10:
case V4L2_PIX_FMT_SGRBG10:
@@ -38,6 +34,12 @@ gles2_debayer_new(int format)
case V4L2_PIX_FMT_SRGGB12:
shader = SHADER_DEBAYER;
break;
case V4L2_PIX_FMT_SBGGR10P:
case V4L2_PIX_FMT_SGBRG10P:
case V4L2_PIX_FMT_SGRBG10P:
case V4L2_PIX_FMT_SRGGB10P:
shader = SHADER_DEBAYER_PACKED;
break;
case V4L2_PIX_FMT_YUYV:
shader = SHADER_YUV;
break;
@@ -65,11 +67,11 @@ gles2_debayer_new(int format)
snprintf(shader_vertex,
64,
"/org/postmarketos/Megapixels/%s.vert",
shader == SHADER_DEBAYER ? "debayer" : "yuv");
gles2_shader_to_vertex(shader));
snprintf(shader_fragment,
64,
"/org/postmarketos/Megapixels/%s.frag",
shader == SHADER_DEBAYER ? "debayer" : "yuv");
gles2_shader_to_fragment(shader));
GLuint shaders[] = {
gl_util_load_shader(shader_vertex, GL_VERTEX_SHADER, NULL, 0),
@@ -246,3 +248,34 @@ gles2_debayer_process(GLES2Debayer *self, GLuint dst_id, GLuint source_id)
gl_util_draw_quad(self->quad);
}
/* Returns which fragment file to use for a particular shader */
const char*
gles2_shader_to_fragment(int shader)
{
switch (shader) {
case SHADER_DEBAYER:
return "debayer";
case SHADER_DEBAYER_PACKED:
return "debayer_packed";
case SHADER_YUV:
return "yuv";
default:
return "solid";
}
}
/* Returns which vertex file to use for a particular shader */
const char*
gles2_shader_to_vertex(int shader)
{
switch (shader) {
case SHADER_DEBAYER:
case SHADER_DEBAYER_PACKED:
return "debayer";
case SHADER_YUV:
return "yuv";
default:
return "solid";
}
}

View File

@@ -5,7 +5,8 @@
#include <stdio.h>
#define SHADER_DEBAYER 1
#define SHADER_YUV 2
#define SHADER_DEBAYER_PACKED 2
#define SHADER_YUV 3
typedef struct {
int format;
@@ -47,3 +48,6 @@ void gles2_debayer_set_shading(GLES2Debayer *self,
float blacklevel);
void gles2_debayer_process(GLES2Debayer *self, GLuint dst_id, GLuint source_id);
const char* gles2_shader_to_fragment(int shader);
const char* gles2_shader_to_vertex(int shader);