[gtk/matthiasc/color-profiles: 1/3] ngl: Apply gamma to frames
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/color-profiles: 1/3] ngl: Apply gamma to frames
- Date: Thu, 30 Sep 2021 05:13:38 +0000 (UTC)
commit da3e439905a773eaf7e663c5a479ac92b4ca7532
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Sep 29 22:15:40 2021 -0400
ngl: Apply gamma to frames
Use a shader to go from linear sRGB to sRGB when
we are done with a frame.
gsk/meson.build | 1 +
gsk/ngl/gsknglprograms.defs | 4 ++++
gsk/ngl/gsknglrenderjob.c | 31 +++++++++++++++++++++++++-
gsk/ngl/resources/postprocessing.glsl | 42 +++++++++++++++++++++++++++++++++++
4 files changed, 77 insertions(+), 1 deletion(-)
---
diff --git a/gsk/meson.build b/gsk/meson.build
index 20fd33185d..eb33866da5 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -19,6 +19,7 @@ gsk_private_ngl_shaders = [
'ngl/resources/repeat.glsl',
'ngl/resources/custom.glsl',
'ngl/resources/filled_border.glsl',
+ 'ngl/resources/postprocessing.glsl',
]
gsk_public_sources = files([
diff --git a/gsk/ngl/gsknglprograms.defs b/gsk/ngl/gsknglprograms.defs
index f4f4a0dfe5..72b383b8fa 100644
--- a/gsk/ngl/gsknglprograms.defs
+++ b/gsk/ngl/gsknglprograms.defs
@@ -82,3 +82,7 @@ GSK_NGL_DEFINE_PROGRAM (unblurred_outset_shadow,
GSK_NGL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread)
GSK_NGL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset)
GSK_NGL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
+
+GSK_NGL_DEFINE_PROGRAM (postprocessing,
+ "/org/gtk/libgsk/ngl/postprocessing.glsl",
+ GSK_NGL_NO_UNIFORMS)
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index 7cfe98fa01..4237756675 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -3993,6 +3993,22 @@ gsk_ngl_render_job_render_flipped (GskNglRenderJob *job,
glDeleteTextures (1, &texture_id);
}
+static void
+gsk_ngl_render_job_postprocess (GskNglRenderJob *job,
+ guint texture_id)
+{
+ GskNglProgram *program = job->driver->postprocessing_no_clip;
+
+ gsk_ngl_command_queue_bind_framebuffer (job->command_queue, job->framebuffer);
+
+ gsk_ngl_render_job_begin_draw (job, program);
+ gsk_ngl_program_set_uniform_texture (job->current_program,
+ UNIFORM_SHARED_SOURCE, 0,
+ GL_TEXTURE_2D, GL_TEXTURE0, texture_id);
+ gsk_ngl_render_job_draw_offscreen_rect (job, &job->viewport);
+ gsk_ngl_render_job_end_draw (job);
+}
+
void
gsk_ngl_render_job_render (GskNglRenderJob *job,
GskRenderNode *root)
@@ -4000,6 +4016,8 @@ gsk_ngl_render_job_render (GskNglRenderJob *job,
G_GNUC_UNUSED gint64 start_time;
guint scale_factor;
guint surface_height;
+ GskNglRenderTarget *render_target;
+ guint texture_id;
g_return_if_fail (job != NULL);
g_return_if_fail (root != NULL);
@@ -4010,15 +4028,26 @@ gsk_ngl_render_job_render (GskNglRenderJob *job,
gsk_ngl_command_queue_make_current (job->command_queue);
+ gsk_ngl_driver_create_render_target (job->driver,
+ job->viewport.size.width,
+ job->viewport.size.height,
+ GL_NEAREST,
+ GL_NEAREST,
+ &render_target);
+
/* Build the command queue using the shared GL context for all renderers
* on the same display.
*/
start_time = GDK_PROFILER_CURRENT_TIME;
gdk_gl_context_push_debug_group (job->command_queue->context, "Building command queue");
- gsk_ngl_command_queue_bind_framebuffer (job->command_queue, job->framebuffer);
+ gsk_ngl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
gsk_ngl_command_queue_clear (job->command_queue, 0, &job->viewport);
gsk_ngl_render_job_visit_node (job, root);
gdk_gl_context_pop_debug_group (job->command_queue->context);
+
+ texture_id = gsk_ngl_driver_release_render_target (job->driver, render_target, FALSE);
+ gsk_ngl_render_job_postprocess (job, texture_id);
+
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Build GL command queue", "");
#if 0
diff --git a/gsk/ngl/resources/postprocessing.glsl b/gsk/ngl/resources/postprocessing.glsl
new file mode 100644
index 0000000000..904da6ef2b
--- /dev/null
+++ b/gsk/ngl/resources/postprocessing.glsl
@@ -0,0 +1,42 @@
+
+// VERTEX_SHADER:
+// postprocessing.glsl
+
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+// postprocessing.glsl
+float u_gamma = 2.2;
+
+vec4 gsk_unpremultiply(vec4 c)
+{
+ if (c.a != 0)
+ return vec4(c.rgb / c.a, c.a);
+ else
+ return c;
+}
+
+vec4 gsk_srgb_to_linear(vec4 srgb)
+{
+ vec3 linear_rgb = pow(srgb.rgb, vec3(u_gamma));
+ return vec4(linear_rgb, srgb.a);
+}
+
+vec4 gsk_linear_to_srgb(vec4 linear_rgba)
+{
+ vec3 srgb = pow(linear_rgba.rgb , vec3(1/u_gamma));
+ return vec4(srgb, linear_rgba.a);
+}
+void main() {
+ vec4 diffuse = GskTexture(u_source, vUv);
+
+ diffuse = gsk_unpremultiply(diffuse);
+ diffuse = gsk_linear_to_srgb(diffuse);
+ diffuse = gsk_premultiply(diffuse);
+
+ gskSetOutputColor(diffuse);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]