gles2_debayer.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include "gles2_debayer.h"
  2. #include "camera.h"
  3. #include "dcp.h"
  4. #include "gl_util.h"
  5. #include "matrix.h"
  6. #include <stdlib.h>
  7. #define VERTEX_ATTRIBUTE 0
  8. #define TEX_COORD_ATTRIBUTE 1
  9. GLES2Debayer *
  10. gles2_debayer_new(int format)
  11. {
  12. // Cannot run on format 0 (Undefined)
  13. assert(format != 0);
  14. uint32_t pixfmt = libmegapixels_format_to_v4l_pixfmt(format);
  15. int shader = 0;
  16. if (pixfmt == V4L2_PIX_FMT_SBGGR8 || pixfmt == V4L2_PIX_FMT_SGBRG8 ||
  17. pixfmt == V4L2_PIX_FMT_SGRBG8 || pixfmt == V4L2_PIX_FMT_SRGGB8 ||
  18. pixfmt == V4L2_PIX_FMT_SBGGR10P || pixfmt == V4L2_PIX_FMT_SGBRG10P ||
  19. pixfmt == V4L2_PIX_FMT_SGRBG10P || pixfmt == V4L2_PIX_FMT_SRGGB10P) {
  20. shader = SHADER_DEBAYER;
  21. } else if (pixfmt == V4L2_PIX_FMT_YUYV) {
  22. shader = SHADER_YUV;
  23. } else {
  24. return NULL;
  25. }
  26. GLuint frame_buffer;
  27. glGenFramebuffers(1, &frame_buffer);
  28. check_gl();
  29. char format_def[64];
  30. snprintf(format_def,
  31. 64,
  32. "#define CFA_%s\n#define BITS_%d\n",
  33. libmegapixels_format_cfa(format),
  34. libmegapixels_format_bits_per_pixel(format));
  35. const GLchar *def[1] = { format_def };
  36. char shader_vertex[64];
  37. char shader_fragment[64];
  38. snprintf(shader_vertex,
  39. 64,
  40. "/org/postmarketos/Megapixels/%s.vert",
  41. shader == SHADER_DEBAYER ? "debayer" : "yuv");
  42. snprintf(shader_fragment,
  43. 64,
  44. "/org/postmarketos/Megapixels/%s.frag",
  45. shader == SHADER_DEBAYER ? "debayer" : "yuv");
  46. GLuint shaders[] = {
  47. gl_util_load_shader(shader_vertex, GL_VERTEX_SHADER, NULL, 0),
  48. gl_util_load_shader(shader_fragment, GL_FRAGMENT_SHADER, def, 1),
  49. };
  50. printf("Using shader %s and %s\n", shader_vertex, shader_fragment);
  51. GLuint program = gl_util_link_program(shaders, 2);
  52. glBindAttribLocation(program, VERTEX_ATTRIBUTE, "vert");
  53. glBindAttribLocation(program, TEX_COORD_ATTRIBUTE, "tex_coord");
  54. check_gl();
  55. GLES2Debayer *self = malloc(sizeof(GLES2Debayer));
  56. self->format = format;
  57. self->shader = shader;
  58. self->frame_buffer = frame_buffer;
  59. self->program = program;
  60. self->uniform_transform = glGetUniformLocation(self->program, "transform");
  61. self->uniform_pixel_size = glGetUniformLocation(self->program, "pixel_size");
  62. self->uniform_padding_ratio =
  63. glGetUniformLocation(self->program, "padding_ratio");
  64. self->uniform_texture = glGetUniformLocation(self->program, "texture");
  65. self->uniform_color_matrix =
  66. glGetUniformLocation(self->program, "color_matrix");
  67. self->uniform_inv_gamma = glGetUniformLocation(self->program, "inv_gamma");
  68. self->uniform_blacklevel = glGetUniformLocation(self->program, "blacklevel");
  69. if (libmegapixels_format_bits_per_pixel(self->format) == 10)
  70. self->uniform_row_length =
  71. glGetUniformLocation(self->program, "row_length");
  72. check_gl();
  73. self->quad = gl_util_new_quad();
  74. return self;
  75. }
  76. void
  77. gles2_debayer_free(GLES2Debayer *self)
  78. {
  79. glDeleteFramebuffers(1, &self->frame_buffer);
  80. glDeleteProgram(self->program);
  81. free(self);
  82. }
  83. void
  84. gles2_debayer_use(GLES2Debayer *self)
  85. {
  86. assert(self != NULL);
  87. glUseProgram(self->program);
  88. check_gl();
  89. gl_util_bind_quad(self->quad);
  90. }
  91. void
  92. gles2_debayer_set_shading(GLES2Debayer *self,
  93. float red,
  94. float blue,
  95. float blacklevel)
  96. {
  97. if (self->forward_matrix[0]) {
  98. float wb[9] = {
  99. // clang-format off
  100. red, 0, 0,
  101. 0, 1, 0,
  102. 0, 0, blue,
  103. // clang-format on
  104. };
  105. float colormat[9];
  106. float xyz[9];
  107. float xyzd65[9];
  108. multiply_matrices(wb, self->forward_matrix, xyz);
  109. multiply_matrices(xyz, XYZD50_to_D65, xyzd65);
  110. multiply_matrices(xyzd65, XYZD65_to_sRGB, colormat);
  111. glUniformMatrix3fv(
  112. self->uniform_color_matrix, 1, GL_FALSE, colormat);
  113. } else if (self->shader == SHADER_YUV) {
  114. glUniformMatrix3fv(
  115. self->uniform_color_matrix, 1, GL_FALSE, YUV_to_RGB);
  116. } else {
  117. glUniformMatrix3fv(
  118. self->uniform_color_matrix, 1, GL_FALSE, IDENTITY);
  119. }
  120. check_gl();
  121. glUniform1f(self->uniform_blacklevel, blacklevel);
  122. check_gl();
  123. }
  124. void
  125. gles2_debayer_configure(GLES2Debayer *self,
  126. const uint32_t dst_width,
  127. const uint32_t dst_height,
  128. const uint32_t src_width,
  129. const uint32_t src_height,
  130. const uint32_t rotation,
  131. const bool mirrored,
  132. struct MPCameraCalibration calibration)
  133. {
  134. glViewport(0, 0, (int)dst_width, (int)dst_height);
  135. check_gl();
  136. /* Rotation matrix for orientation correction */
  137. GLfloat rotation_list[4] = { 0, -1, 0, 1 };
  138. int rotation_index = 4 - (int)rotation / 90;
  139. GLfloat sin_rot = rotation_list[rotation_index];
  140. GLfloat cos_rot = rotation_list[(rotation_index + 1) % 4];
  141. GLfloat scale_x = mirrored ? 1 : -1;
  142. GLfloat matrix[9] = {
  143. // clang-format off
  144. cos_rot * scale_x, sin_rot, 0,
  145. -sin_rot * scale_x, cos_rot, 0,
  146. 0, 0, 1,
  147. // clang-format on
  148. };
  149. glUniformMatrix3fv(self->uniform_transform, 1, GL_FALSE, matrix);
  150. check_gl();
  151. GLfloat pixel_size_x = 1.0f / src_width;
  152. GLfloat pixel_size_y = 1.0f / src_height;
  153. glUniform2f(self->uniform_pixel_size, pixel_size_x, pixel_size_y);
  154. check_gl();
  155. /* Color calibration curves and matrices */
  156. float gamma = 1.0f;
  157. for (int i = 2; i < calibration.tone_curve_length; i += 2) {
  158. float g = calibration.tone_curve[i + 1] / calibration.tone_curve[i];
  159. if (g > gamma) {
  160. gamma = g;
  161. }
  162. }
  163. glUniform1f(self->uniform_inv_gamma, 1.0f / gamma);
  164. check_gl();
  165. for (int i = 0; i < 9; i++) {
  166. self->forward_matrix[i] = calibration.forward_matrix_1[i];
  167. }
  168. gles2_debayer_set_shading(self, 1.0f, 1.0f, 0.0f);
  169. GLuint row_length =
  170. libmegapixels_mode_width_to_bytes(self->format, src_width);
  171. if (libmegapixels_format_bits_per_pixel(self->format) == 10) {
  172. assert(src_width % 4 == 0);
  173. glUniform1f(self->uniform_row_length, row_length);
  174. check_gl();
  175. }
  176. GLuint padding_bytes =
  177. libmegapixels_mode_width_to_padding(self->format, src_width);
  178. GLfloat padding_ratio = (float)row_length / (row_length + padding_bytes);
  179. glUniform1f(self->uniform_padding_ratio, padding_ratio);
  180. }
  181. void
  182. gles2_debayer_process(GLES2Debayer *self, GLuint dst_id, GLuint source_id)
  183. {
  184. glBindFramebuffer(GL_FRAMEBUFFER, self->frame_buffer);
  185. glBindTexture(GL_TEXTURE_2D, dst_id);
  186. glFramebufferTexture2D(
  187. GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_id, 0);
  188. check_gl();
  189. assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
  190. glActiveTexture(GL_TEXTURE0);
  191. glBindTexture(GL_TEXTURE_2D, source_id);
  192. glUniform1i(self->uniform_texture, 0);
  193. check_gl();
  194. gl_util_draw_quad(self->quad);
  195. }