瀏覽代碼

Second pass at OpenGL debayering

Benjamin Schaaf 4 年之前
父節點
當前提交
aa8b2409d9
共有 5 個文件被更改,包括 140 次插入12 次删除
  1. 9 1
      data/debayer.frag
  2. 2 0
      data/debayer.vert
  3. 67 8
      gl_quickpreview.c
  4. 61 2
      process_pipeline.c
  5. 1 1
      quickpreview.c

+ 9 - 1
data/debayer.frag

@@ -1,6 +1,8 @@
 precision mediump float;
 
 uniform sampler2D texture;
+// uniform sampler2D srgb_map;
+uniform mat3 color_matrix;
 
 varying vec2 uv1;
 varying vec2 uv2;
@@ -24,5 +26,11 @@ void main() {
 		mix(pixels.yzw, pixels.xyz, is_top_left.y),
 		is_top_left.x);
 
-	gl_FragColor = vec4(color, 0);
+	vec3 srgb_color = pow(color, vec3(1.0 / 2.2));
+	// vec3 srgb_color = vec3(
+	// 	texture2D(srgb_map, vec2(color.r, 0)).r,
+	// 	texture2D(srgb_map, vec2(color.g, 0)).r,
+	// 	texture2D(srgb_map, vec2(color.b, 0)).r);
+
+	gl_FragColor = vec4((color_matrix * srgb_color).bgr, 0);
 }

+ 2 - 0
data/debayer.vert

@@ -13,6 +13,8 @@ varying vec2 pixel_coord;
 void main() {
 	uv1 = tex_coord - pixel_size / 2.0;
 	uv2 = tex_coord + pixel_size / 2.0;
+	uv1 += pixel_size;
+	uv2 += pixel_size;
 	pixel_coord = uv1 / pixel_size;
 
 	gl_Position = vec4(transform * vec3(vert, 1), 1);

+ 67 - 8
gl_quickpreview.c

@@ -27,6 +27,9 @@ struct _GLQuickPreview {
 	GLuint uniform_transform;
 	GLuint uniform_pixel_size;
 	GLuint uniform_texture;
+	GLuint uniform_srgb_map;
+	GLuint uniform_color_matrix;
+	GLuint srgb_texture;
 };
 
 static GLuint load_shader(const char *path, GLenum type)
@@ -73,6 +76,27 @@ static GLuint load_shader(const char *path, GLenum type)
 	return shader;
 }
 
+// static const uint8_t srgb[] = {
+// 	0, 12, 21, 28, 33, 38, 42, 46, 49, 52, 55, 58, 61, 63, 66, 68, 70,
+// 	73, 75, 77, 79, 81, 82, 84, 86, 88, 89, 91, 93, 94, 96, 97, 99, 100,
+// 	102, 103, 104, 106, 107, 109, 110, 111, 112, 114, 115, 116, 117, 118,
+// 	120, 121, 122, 123, 124, 125, 126, 127, 129, 130, 131, 132, 133, 134,
+// 	135, 136, 137, 138, 139, 140, 141, 142, 142, 143, 144, 145, 146, 147,
+// 	148, 149, 150, 151, 151, 152, 153, 154, 155, 156, 157, 157, 158, 159,
+// 	160, 161, 161, 162, 163, 164, 165, 165, 166, 167, 168, 168, 169, 170,
+// 	171, 171, 172, 173, 174, 174, 175, 176, 176, 177, 178, 179, 179, 180,
+// 	181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189,
+// 	190, 191, 191, 192, 193, 193, 194, 194, 195, 196, 196, 197, 197, 198,
+// 	199, 199, 200, 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206,
+// 	207, 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214,
+// 	215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222,
+// 	222, 223, 223, 224, 224, 225, 226, 226, 227, 227, 228, 228, 229, 229,
+// 	230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235, 236, 236,
+// 	237, 237, 237, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242, 243,
+// 	243, 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249,
+// 	250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255
+// };
+
 GLQuickPreview *gl_quick_preview_new()
 {
 	GLuint frame_buffer;
@@ -87,9 +111,7 @@ GLQuickPreview *gl_quick_preview_new()
 	glAttachShader(program, frag);
 
 	glBindAttribLocation(program, VERTEX_ATTRIBUTE, "vert");
-	check_gl();
 	glBindAttribLocation(program, TEX_COORD_ATTRIBUTE, "tex_coord");
-	check_gl();
 	glLinkProgram(program);
 	check_gl();
 
@@ -108,22 +130,35 @@ GLQuickPreview *gl_quick_preview_new()
 		printf("Program log: %s\n", log);
 		free(log);
 	}
+	check_gl();
+
+	// GLuint srgb_texture;
+	// glGenTextures(1, &srgb_texture);
+	// check_gl();
 
+	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 	check_gl();
 
+	// glBindTexture(GL_TEXTURE_2D, srgb_texture);
+	// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	// check_gl();
+	// glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 256, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, srgb);
+	// check_gl();
+	// glBindTexture(GL_TEXTURE_2D, 0);
+
 	GLQuickPreview *self = malloc(sizeof(GLQuickPreview));
 	self->frame_buffer = frame_buffer;
 	self->program = program;
 
 	self->uniform_transform = glGetUniformLocation(self->program, "transform");
-	check_gl();
-
 	self->uniform_pixel_size = glGetUniformLocation(self->program, "pixel_size");
-	check_gl();
-
 	self->uniform_texture = glGetUniformLocation(self->program, "texture");
-	check_gl();
-
+	self->uniform_color_matrix = glGetUniformLocation(self->program, "color_matrix");
+	self->uniform_srgb_map = glGetUniformLocation(self->program, "srgb_map");
+	// self->srgb_texture = srgb_texture;
 	return self;
 }
 
@@ -191,6 +226,30 @@ gl_quick_preview(GLQuickPreview *self,
 	glUniform1i(self->uniform_texture, 0);
 	check_gl();
 
+	// glActiveTexture(GL_TEXTURE1);
+	// glBindTexture(GL_TEXTURE_2D, self->srgb_texture);
+	// glUniform1i(self->uniform_srgb_map, 1);
+	// check_gl();
+
+	if (colormatrix)
+	{
+		GLfloat transposed[9];
+		for (int i = 0; i < 3; ++i)
+			for (int j = 0; j < 3; ++j)
+				transposed[i + j * 3] = colormatrix[j + i * 3];
+
+		glUniformMatrix3fv(self->uniform_color_matrix, 1, GL_FALSE, transposed);
+	}
+	else
+	{
+		static const GLfloat identity[9] = {
+			1, 0, 0,
+			0, 1, 0,
+			0, 0, 1,
+		};
+		glUniformMatrix3fv(self->uniform_color_matrix, 1, GL_FALSE, identity);
+	}
+
 	glVertexAttribPointer(VERTEX_ATTRIBUTE, 2, GL_FLOAT, 0, 0, square_vertices);
 	check_gl();
 	glEnableVertexAttribArray(VERTEX_ATTRIBUTE);

+ 61 - 2
process_pipeline.c

@@ -17,6 +17,8 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <gdk/gdkwayland.h>
+#include <sys/mman.h>
+#include <drm/drm_fourcc.h>
 
 #define TIFFTAG_FORWARDMATRIX1 50964
 
@@ -166,6 +168,7 @@ static EGLContext egl_context = EGL_NO_CONTEXT;
 // static struct buffer output_buffers[NUM_BUFFERS];
 
 static PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA;
+static PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC eglExportDMABUFImageQueryMESA;
 
 static const char *
 egl_get_error_str()
@@ -276,6 +279,8 @@ init_gl(MPPipeline *pipeline, GdkWindow **window)
 
 	eglExportDMABUFImageMESA = (PFNEGLEXPORTDMABUFIMAGEMESAPROC)
 		eglGetProcAddress("eglExportDMABUFImageMESA");
+	eglExportDMABUFImageQueryMESA = (PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC)
+		eglGetProcAddress("eglExportDMABUFImageQueryMESA");
 
 	// Generate textures for the buffers
 	// GLuint textures[NUM_BUFFERS * 2];
@@ -292,7 +297,6 @@ init_gl(MPPipeline *pipeline, GdkWindow **window)
 	// 	output_buffers[i].dma_fd = -1;
 	// }
 
-	check_gl();
 	gl_quick_preview_state = gl_quick_preview_new();
 	check_gl();
 
@@ -310,6 +314,8 @@ process_image_for_preview(const uint8_t *image)
 {
 	cairo_surface_t *surface;
 
+	clock_t t1 = clock();
+
 	if (gl_quick_preview_state && ql_quick_preview_supports_format(gl_quick_preview_state, mode.pixel_format)) {
 #ifdef RENDERDOC
 		if (rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
@@ -323,6 +329,8 @@ process_image_for_preview(const uint8_t *image)
 		glBindTexture(GL_TEXTURE_2D, textures[0]);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 		glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, mode.width, mode.height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
 		check_gl();
 
@@ -344,7 +352,58 @@ process_image_for_preview(const uint8_t *image)
 
 		surface = cairo_image_surface_create(
 			CAIRO_FORMAT_RGB24, preview_width, preview_height);
-		uint8_t *pixels = cairo_image_surface_get_data(surface);
+		uint32_t *pixels = (uint32_t *)cairo_image_surface_get_data(surface);
+		glFinish();
+
+		clock_t t2 = clock();
+		printf("%fms\n", (float)(t2 - t1) / CLOCKS_PER_SEC * 1000);
+
+		// {
+		// 	glBindTexture(GL_TEXTURE_2D, textures[1]);
+		// 	EGLImage egl_image = eglCreateImage(egl_display, egl_context, EGL_GL_TEXTURE_2D, (EGLClientBuffer)(size_t)textures[1], NULL);
+
+		// 	// Make sure it's in the expected format
+		// 	int fourcc;
+		// 	eglExportDMABUFImageQueryMESA(egl_display, egl_image, &fourcc, NULL, NULL);
+		// 	assert(fourcc == DRM_FORMAT_ABGR8888);
+
+
+		// 	int dmabuf_fd;
+		// 	int stride, offset;
+		// 	eglExportDMABUFImageMESA(egl_display, egl_image, &dmabuf_fd, &stride, &offset);
+
+		// 	int fsize = lseek(dmabuf_fd, 0, SEEK_END);
+		// 	printf("SIZE %d STRIDE %d OFFSET %d SIZE %d:%d\n", fsize, stride, offset, preview_width, preview_height);
+
+		// 	size_t size = stride * preview_height;
+		// 	uint32_t *data = mmap(NULL, fsize, PROT_READ, MAP_SHARED, dmabuf_fd, 0);
+		// 	assert(data != MAP_FAILED);
+
+		// 	int pixel_stride = stride / 4;
+
+		// 	for (size_t y = 0; y < preview_height; ++y) {
+		// 		for (size_t x = 0; x < preview_width; ++x) {
+		// 			uint32_t p = data[x + y * pixel_stride];
+		// 			pixels[x + y * preview_width] = p;
+		// 		// 	uint16_t p = data[x + y * stride];
+		// 		// 	uint32_t r = (p & 0b11111);
+		// 		// 	uint32_t g = ((p >> 5) & 0b11111);
+		// 		// 	uint32_t b = ((p >> 10) & 0b11111);
+		// 		// 	pixels[x + y * preview_width] = (r << 16) | (g << 8) | b;
+		// 		}
+		// 		// memcpy(pixels + preview_width * y, data + stride * y, preview_width * sizeof(uint32_t));
+		// 	}
+
+		// 	{
+		// 		FILE *f = fopen("test.raw", "w");
+		// 		fwrite(data, fsize, 1, f);
+		// 		fclose(f);
+		// 	}
+
+		// 	// memcpy(pixels, data, size);
+		// 	munmap(data, size);
+		// 	close(dmabuf_fd);
+		// }
 		glReadPixels(0, 0, preview_width, preview_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 		check_gl();
 

+ 1 - 1
quickpreview.c

@@ -8,7 +8,7 @@
 #include <stdio.h>
 
 /* Linear -> sRGB lookup table */
-static const int srgb[] = {
+static const uint8_t srgb[] = {
 	0, 12, 21, 28, 33, 38, 42, 46, 49, 52, 55, 58, 61, 63, 66, 68, 70,
 	73, 75, 77, 79, 81, 82, 84, 86, 88, 89, 91, 93, 94, 96, 97, 99, 100,
 	102, 103, 104, 106, 107, 109, 110, 111, 112, 114, 115, 116, 117, 118,