diff --git a/data/debayer.frag b/data/debayer.frag index a8f4a36..a9fd0c8 100644 --- a/data/debayer.frag +++ b/data/debayer.frag @@ -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); diff --git a/data/debayer_packed.frag b/data/debayer_packed.frag new file mode 100644 index 0000000..de10180 --- /dev/null +++ b/data/debayer_packed.frag @@ -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); +} diff --git a/src/gles2_debayer.c b/src/gles2_debayer.c index e815b72..ca5ec88 100644 --- a/src/gles2_debayer.c +++ b/src/gles2_debayer.c @@ -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"; + } +} diff --git a/src/gles2_debayer.h b/src/gles2_debayer.h index d5ec6a6..9033552 100644 --- a/src/gles2_debayer.h +++ b/src/gles2_debayer.h @@ -5,7 +5,8 @@ #include #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);