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 mat3 color_matrix;
uniform float inv_gamma; uniform float inv_gamma;
uniform float blacklevel; uniform float blacklevel;
#ifdef BITS_10
uniform float row_length;
uniform float padding_ratio;
#endif
varying vec2 top_left_uv; varying vec2 top_left_uv;
varying vec2 top_right_uv; varying vec2 top_right_uv;
varying vec2 bottom_left_uv; varying vec2 bottom_left_uv;
varying vec2 bottom_right_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 void
main() main()
{ {
// Note the coordinates for texture samples need to be a varying, as the // 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 // 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. // 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, vec4 samples = vec4(texture2D(texture, top_left_uv).r,
texture2D(texture, top_right_uv).r, texture2D(texture, top_right_uv).r,
texture2D(texture, bottom_left_uv).r, texture2D(texture, bottom_left_uv).r,
texture2D(texture, bottom_right_uv).r); texture2D(texture, bottom_right_uv).r);
#endif
#if defined(CFA_BGGR) #if defined(CFA_BGGR)
vec3 color = vec3(samples.w, (samples.y + samples.z) / 2.0, samples.x); 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_SGBRG8:
case V4L2_PIX_FMT_SGRBG8: case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8: 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_SBGGR10:
case V4L2_PIX_FMT_SGBRG10: case V4L2_PIX_FMT_SGBRG10:
case V4L2_PIX_FMT_SGRBG10: case V4L2_PIX_FMT_SGRBG10:
@@ -38,6 +34,12 @@ gles2_debayer_new(int format)
case V4L2_PIX_FMT_SRGGB12: case V4L2_PIX_FMT_SRGGB12:
shader = SHADER_DEBAYER; shader = SHADER_DEBAYER;
break; 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: case V4L2_PIX_FMT_YUYV:
shader = SHADER_YUV; shader = SHADER_YUV;
break; break;
@@ -65,11 +67,11 @@ gles2_debayer_new(int format)
snprintf(shader_vertex, snprintf(shader_vertex,
64, 64,
"/org/postmarketos/Megapixels/%s.vert", "/org/postmarketos/Megapixels/%s.vert",
shader == SHADER_DEBAYER ? "debayer" : "yuv"); gles2_shader_to_vertex(shader));
snprintf(shader_fragment, snprintf(shader_fragment,
64, 64,
"/org/postmarketos/Megapixels/%s.frag", "/org/postmarketos/Megapixels/%s.frag",
shader == SHADER_DEBAYER ? "debayer" : "yuv"); gles2_shader_to_fragment(shader));
GLuint shaders[] = { GLuint shaders[] = {
gl_util_load_shader(shader_vertex, GL_VERTEX_SHADER, NULL, 0), 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); 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> #include <stdio.h>
#define SHADER_DEBAYER 1 #define SHADER_DEBAYER 1
#define SHADER_YUV 2 #define SHADER_DEBAYER_PACKED 2
#define SHADER_YUV 3
typedef struct { typedef struct {
int format; int format;
@@ -47,3 +48,6 @@ void gles2_debayer_set_shading(GLES2Debayer *self,
float blacklevel); float blacklevel);
void gles2_debayer_process(GLES2Debayer *self, GLuint dst_id, GLuint source_id); 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);