mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 13:41:07 +00:00
gsk: Handle straight-alpha dmabufs
This omission was noticed by Benjamin Otte. Add a premultiply uniform to the external shader, and add a separate premultiply shader for the non-external case.
This commit is contained in:
parent
c48a3152f0
commit
79009d4158
@ -1605,7 +1605,6 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
|
|||||||
start_time = GDK_PROFILER_CURRENT_TIME;
|
start_time = GDK_PROFILER_CURRENT_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
glPixelStorei (GL_UNPACK_ALIGNMENT, gdk_memory_format_alignment (data_format));
|
glPixelStorei (GL_UNPACK_ALIGNMENT, gdk_memory_format_alignment (data_format));
|
||||||
|
|
||||||
/* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
|
/* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
|
||||||
|
@ -807,6 +807,8 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
|||||||
GskGLRenderTarget *render_target;
|
GskGLRenderTarget *render_target;
|
||||||
guint prev_fbo;
|
guint prev_fbo;
|
||||||
gboolean external;
|
gboolean external;
|
||||||
|
GdkMemoryFormat format;
|
||||||
|
gboolean premultiply;
|
||||||
|
|
||||||
gdk_gl_context_make_current (context);
|
gdk_gl_context_make_current (context);
|
||||||
|
|
||||||
@ -822,6 +824,8 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (texture);
|
dmabuf = gdk_dmabuf_texture_get_dmabuf (texture);
|
||||||
|
format = gdk_texture_get_format (GDK_TEXTURE (texture));
|
||||||
|
premultiply = gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT;
|
||||||
|
|
||||||
texture_id = gdk_gl_context_import_dmabuf (context,
|
texture_id = gdk_gl_context_import_dmabuf (context,
|
||||||
width, height,
|
width, height,
|
||||||
@ -830,12 +834,15 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
|||||||
if (texture_id == 0)
|
if (texture_id == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!external)
|
if (!external && !premultiply)
|
||||||
return texture_id;
|
return texture_id;
|
||||||
|
|
||||||
gsk_gl_driver_autorelease_texture (self, texture_id);
|
gsk_gl_driver_autorelease_texture (self, texture_id);
|
||||||
|
|
||||||
program = self->external;
|
if (external)
|
||||||
|
program = self->external;
|
||||||
|
else
|
||||||
|
program = self->premultiply;
|
||||||
|
|
||||||
if (!gsk_gl_driver_create_render_target (self, width, height, GL_RGBA8, &render_target))
|
if (!gsk_gl_driver_create_render_target (self, width, height, GL_RGBA8, &render_target))
|
||||||
return texture_id;
|
return texture_id;
|
||||||
@ -849,9 +856,20 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
|||||||
set_viewport_for_size (self, program, width, height);
|
set_viewport_for_size (self, program, width, height);
|
||||||
reset_modelview (self, program);
|
reset_modelview (self, program);
|
||||||
|
|
||||||
gsk_gl_program_set_uniform_texture (program,
|
if (external)
|
||||||
UNIFORM_EXTERNAL_SOURCE, 0,
|
{
|
||||||
GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE0, texture_id);
|
gsk_gl_program_set_uniform_texture (program,
|
||||||
|
UNIFORM_EXTERNAL_SOURCE, 0,
|
||||||
|
GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE0, texture_id);
|
||||||
|
|
||||||
|
gsk_gl_program_set_uniform1i (program, UNIFORM_PREMULTIPLY, 0, premultiply);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gsk_gl_program_set_uniform_texture (program,
|
||||||
|
UNIFORM_SHARED_SOURCE, 0,
|
||||||
|
GL_TEXTURE_2D, GL_TEXTURE0, texture_id);
|
||||||
|
}
|
||||||
|
|
||||||
draw_rect (self->command_queue, 0, 0, width, height);
|
draw_rect (self->command_queue, 0, 0, width, height);
|
||||||
|
|
||||||
|
@ -96,4 +96,9 @@ GSK_GL_DEFINE_PROGRAM (unblurred_outset_shadow,
|
|||||||
|
|
||||||
GSK_GL_DEFINE_PROGRAM_NO_CLIP (external,
|
GSK_GL_DEFINE_PROGRAM_NO_CLIP (external,
|
||||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("external.glsl")),
|
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("external.glsl")),
|
||||||
GSK_GL_ADD_UNIFORM (1, EXTERNAL_SOURCE, u_external_source))
|
GSK_GL_ADD_UNIFORM (1, EXTERNAL_SOURCE, u_external_source)
|
||||||
|
GSK_GL_ADD_UNIFORM (2, PREMULTIPLY, u_premultiply))
|
||||||
|
|
||||||
|
GSK_GL_DEFINE_PROGRAM_NO_CLIP (premultiply,
|
||||||
|
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("premultiply.glsl")),
|
||||||
|
GSK_GL_NO_UNIFORMS)
|
||||||
|
@ -17,6 +17,8 @@ uniform samplerExternalOES u_external_source;
|
|||||||
uniform sampler2D u_external_source;
|
uniform sampler2D u_external_source;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uniform int u_premultiply;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
/* Open-code this here, since GskTexture() expects a sampler2D */
|
/* Open-code this here, since GskTexture() expects a sampler2D */
|
||||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||||
@ -24,5 +26,9 @@ void main() {
|
|||||||
#else
|
#else
|
||||||
vec4 color = texture(u_external_source, vUv);
|
vec4 color = texture(u_external_source, vUv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (u_premultiply == 1)
|
||||||
|
color.rgb *= color.a;
|
||||||
|
|
||||||
gskSetOutputColor(color);
|
gskSetOutputColor(color);
|
||||||
}
|
}
|
||||||
|
19
gsk/gl/resources/premultiply.glsl
Normal file
19
gsk/gl/resources/premultiply.glsl
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// VERTEX_SHADER:
|
||||||
|
// premultiply.glsl
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||||
|
|
||||||
|
vUv = vec2(aUv.x, aUv.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FRAGMENT_SHADER:
|
||||||
|
// premultiply.glsl
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 color = GskTexture(u_source, vUv);
|
||||||
|
|
||||||
|
color.rgb *= color.a;
|
||||||
|
|
||||||
|
gskSetOutputColor(color);
|
||||||
|
}
|
@ -21,6 +21,7 @@ gsk_private_gl_shaders = [
|
|||||||
'gl/resources/filled_border.glsl',
|
'gl/resources/filled_border.glsl',
|
||||||
'gl/resources/mask.glsl',
|
'gl/resources/mask.glsl',
|
||||||
'gl/resources/external.glsl',
|
'gl/resources/external.glsl',
|
||||||
|
'gl/resources/premultiply.glsl',
|
||||||
]
|
]
|
||||||
|
|
||||||
gsk_public_sources = files([
|
gsk_public_sources = files([
|
||||||
|
Loading…
Reference in New Issue
Block a user