Переглянути джерело

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

Kristian Vos 5 місяців тому
батько
коміт
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);