فهرست منبع

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

Kristian Vos 10 ماه پیش
والد
کامیت
32f168b6d8
4فایلهای تغییر یافته به همراه103 افزوده شده و 34 حذف شده
  1. 0 27
      data/debayer.frag
  2. 59 0
      data/debayer_packed.frag
  3. 39 6
      src/gles2_debayer.c
  4. 5 1
      src/gles2_debayer.h

+ 0 - 27
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);

+ 59 - 0
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);
+}

+ 39 - 6
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";
+        }
+}

+ 5 - 1
src/gles2_debayer.h

@@ -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);