mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-11 13:10:07 +00:00
gpu: Add a cross-fade shader
This commit is contained in:
parent
2a5f6fdde5
commit
b9651606d3
84
gsk/gpu/gskgpucrossfadeop.c
Normal file
84
gsk/gpu/gskgpucrossfadeop.c
Normal file
@ -0,0 +1,84 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskgpucrossfadeopprivate.h"
|
||||
|
||||
#include "gskgpuframeprivate.h"
|
||||
#include "gskgpuprintprivate.h"
|
||||
#include "gskrectprivate.h"
|
||||
|
||||
#include "gpu/shaders/gskgpucrossfadeinstance.h"
|
||||
|
||||
typedef struct _GskGpuCrossFadeOp GskGpuCrossFadeOp;
|
||||
|
||||
struct _GskGpuCrossFadeOp
|
||||
{
|
||||
GskGpuShaderOp op;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cross_fade_op_print (GskGpuOp *op,
|
||||
GskGpuFrame *frame,
|
||||
GString *string,
|
||||
guint indent)
|
||||
{
|
||||
GskGpuShaderOp *shader = (GskGpuShaderOp *) op;
|
||||
GskGpuCrossfadeInstance *instance;
|
||||
|
||||
instance = (GskGpuCrossfadeInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
|
||||
|
||||
gsk_gpu_print_op (string, indent, "cross-fade");
|
||||
gsk_gpu_print_rect (string, instance->rect);
|
||||
gsk_gpu_print_image_descriptor (string, shader->desc, instance->start_id);
|
||||
gsk_gpu_print_image_descriptor (string, shader->desc, instance->end_id);
|
||||
g_string_append_printf (string, "%g%%", 100 * instance->opacity_progress[1]);
|
||||
gsk_gpu_print_newline (string);
|
||||
}
|
||||
|
||||
static const GskGpuShaderOpClass GSK_GPU_CROSS_FADE_OP_CLASS = {
|
||||
{
|
||||
GSK_GPU_OP_SIZE (GskGpuCrossFadeOp),
|
||||
GSK_GPU_STAGE_SHADER,
|
||||
gsk_gpu_shader_op_finish,
|
||||
gsk_gpu_cross_fade_op_print,
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
gsk_gpu_shader_op_vk_command,
|
||||
#endif
|
||||
gsk_gpu_shader_op_gl_command
|
||||
},
|
||||
"gskgpucrossfade",
|
||||
sizeof (GskGpuCrossfadeInstance),
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
&gsk_gpu_crossfade_info,
|
||||
#endif
|
||||
gsk_gpu_crossfade_setup_vao
|
||||
};
|
||||
|
||||
void
|
||||
gsk_gpu_cross_fade_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *offset,
|
||||
float opacity,
|
||||
float progress,
|
||||
guint32 start_descriptor,
|
||||
const graphene_rect_t *start_rect,
|
||||
guint32 end_descriptor,
|
||||
const graphene_rect_t *end_rect)
|
||||
{
|
||||
GskGpuCrossfadeInstance *instance;
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_CROSS_FADE_OP_CLASS,
|
||||
clip,
|
||||
desc,
|
||||
&instance);
|
||||
|
||||
gsk_gpu_rect_to_float (rect, offset, instance->rect);
|
||||
instance->opacity_progress[0] = opacity;
|
||||
instance->opacity_progress[1] = progress;
|
||||
gsk_gpu_rect_to_float (start_rect, offset, instance->start_rect);
|
||||
instance->start_id = start_descriptor;
|
||||
gsk_gpu_rect_to_float (end_rect, offset, instance->end_rect);
|
||||
instance->end_id = end_descriptor;
|
||||
}
|
23
gsk/gpu/gskgpucrossfadeopprivate.h
Normal file
23
gsk/gpu/gskgpucrossfadeopprivate.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "gskgpushaderopprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_cross_fade_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *offset,
|
||||
float opacity,
|
||||
float progress,
|
||||
guint32 start_descriptor,
|
||||
const graphene_rect_t *start_rect,
|
||||
guint32 end_descriptor,
|
||||
const graphene_rect_t *end_rect);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "gskgpucolormatrixopprivate.h"
|
||||
#include "gskgpucoloropprivate.h"
|
||||
#include "gskgpuconicgradientopprivate.h"
|
||||
#include "gskgpucrossfadeopprivate.h"
|
||||
#include "gskgpudescriptorsprivate.h"
|
||||
#include "gskgpudeviceprivate.h"
|
||||
#include "gskgpuframeprivate.h"
|
||||
@ -2556,6 +2557,88 @@ gsk_gpu_node_processor_create_blend_pattern (GskGpuPatternWriter *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_node_processor_add_cross_fade_node (GskGpuNodeProcessor *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
GskRenderNode *start_child, *end_child;
|
||||
graphene_rect_t start_rect, end_rect;
|
||||
GskGpuImage *start_image, *end_image;
|
||||
guint32 descriptors[2];
|
||||
float progress, old_opacity;
|
||||
|
||||
start_child = gsk_cross_fade_node_get_start_child (node);
|
||||
end_child = gsk_cross_fade_node_get_end_child (node);
|
||||
progress = gsk_cross_fade_node_get_progress (node);
|
||||
|
||||
if ((gsk_gpu_node_processor_ubershader_instead_of_offscreen (self, start_child) ||
|
||||
gsk_gpu_node_processor_ubershader_instead_of_offscreen (self, end_child)) &&
|
||||
gsk_gpu_node_processor_try_node_as_pattern (self, node))
|
||||
return;
|
||||
|
||||
start_image = gsk_gpu_node_processor_get_node_as_image (self,
|
||||
0,
|
||||
GSK_GPU_IMAGE_STRAIGHT_ALPHA,
|
||||
NULL,
|
||||
start_child,
|
||||
&start_rect);
|
||||
end_image = gsk_gpu_node_processor_get_node_as_image (self,
|
||||
0,
|
||||
GSK_GPU_IMAGE_STRAIGHT_ALPHA,
|
||||
NULL,
|
||||
end_child,
|
||||
&end_rect);
|
||||
|
||||
if (start_image == NULL)
|
||||
{
|
||||
if (end_image == NULL)
|
||||
return;
|
||||
|
||||
old_opacity = self->opacity;
|
||||
self->opacity *= progress;
|
||||
gsk_gpu_node_processor_image_op (self,
|
||||
end_image,
|
||||
&end_child->bounds,
|
||||
&end_rect);
|
||||
g_object_unref (end_image);
|
||||
self->opacity = old_opacity;
|
||||
return;
|
||||
}
|
||||
else if (end_image == NULL)
|
||||
{
|
||||
old_opacity = self->opacity;
|
||||
self->opacity *= (1 - progress);
|
||||
gsk_gpu_node_processor_image_op (self,
|
||||
start_image,
|
||||
&start_child->bounds,
|
||||
&start_rect);
|
||||
g_object_unref (start_image);
|
||||
self->opacity = old_opacity;
|
||||
return;
|
||||
}
|
||||
|
||||
gsk_gpu_node_processor_add_images (self,
|
||||
2,
|
||||
(GskGpuImage *[2]) { start_image, end_image },
|
||||
(GskGpuSampler[2]) { GSK_GPU_SAMPLER_DEFAULT, GSK_GPU_SAMPLER_DEFAULT },
|
||||
descriptors);
|
||||
|
||||
gsk_gpu_cross_fade_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
self->desc,
|
||||
&node->bounds,
|
||||
&self->offset,
|
||||
self->opacity,
|
||||
progress,
|
||||
descriptors[0],
|
||||
&start_rect,
|
||||
descriptors[1],
|
||||
&end_rect);
|
||||
|
||||
g_object_unref (end_image);
|
||||
g_object_unref (start_image);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_node_processor_create_cross_fade_pattern (GskGpuPatternWriter *self,
|
||||
GskRenderNode *node)
|
||||
@ -3640,7 +3723,7 @@ static const struct
|
||||
[GSK_CROSS_FADE_NODE] = {
|
||||
0,
|
||||
GSK_GPU_HANDLE_OPACITY,
|
||||
gsk_gpu_node_processor_add_node_as_pattern,
|
||||
gsk_gpu_node_processor_add_cross_fade_node,
|
||||
gsk_gpu_node_processor_create_cross_fade_pattern,
|
||||
},
|
||||
[GSK_TEXT_NODE] = {
|
||||
|
64
gsk/gpu/shaders/gskgpucrossfade.glsl
Normal file
64
gsk/gpu/shaders/gskgpucrossfade.glsl
Normal file
@ -0,0 +1,64 @@
|
||||
#include "common.glsl"
|
||||
|
||||
PASS(0) vec2 _pos;
|
||||
PASS_FLAT(1) Rect _start_rect;
|
||||
PASS_FLAT(2) Rect _end_rect;
|
||||
PASS(3) vec2 _start_coord;
|
||||
PASS(4) vec2 _end_coord;
|
||||
PASS_FLAT(5) uint _start_id;
|
||||
PASS_FLAT(6) uint _end_id;
|
||||
PASS_FLAT(7) float _start_opacity;
|
||||
PASS_FLAT(8) float _end_opacity;
|
||||
|
||||
|
||||
#ifdef GSK_VERTEX_SHADER
|
||||
|
||||
IN(0) vec4 in_rect;
|
||||
IN(1) vec4 in_start_rect;
|
||||
IN(2) uint in_start_id;
|
||||
IN(3) vec4 in_end_rect;
|
||||
IN(4) uint in_end_id;
|
||||
IN(5) vec2 in_opacity_progress;
|
||||
|
||||
void
|
||||
run (out vec2 pos)
|
||||
{
|
||||
Rect r = rect_from_gsk (in_rect);
|
||||
|
||||
pos = rect_get_position (r);
|
||||
|
||||
_pos = pos;
|
||||
|
||||
Rect start_rect = rect_from_gsk (in_start_rect);
|
||||
_start_rect = start_rect;
|
||||
_start_coord = rect_get_coord (start_rect, pos);
|
||||
_start_id = in_start_id;
|
||||
_start_opacity = in_opacity_progress[0] * (1.0 - in_opacity_progress[1]);
|
||||
|
||||
Rect end_rect = rect_from_gsk (in_end_rect);
|
||||
_end_rect = end_rect;
|
||||
_end_coord = rect_get_coord (end_rect, pos);
|
||||
_end_id = in_end_id;
|
||||
_end_opacity = in_opacity_progress[0] * in_opacity_progress[1];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef GSK_FRAGMENT_SHADER
|
||||
|
||||
void
|
||||
run (out vec4 color,
|
||||
out vec2 position)
|
||||
{
|
||||
color = gsk_texture (_start_id, _start_coord) *
|
||||
rect_coverage (_start_rect, _pos) *
|
||||
_start_opacity +
|
||||
gsk_texture (_end_id, _end_coord) *
|
||||
rect_coverage (_end_rect, _pos) *
|
||||
_end_opacity;
|
||||
position = _pos;
|
||||
}
|
||||
|
||||
#endif
|
@ -20,6 +20,7 @@ gsk_private_gpu_shaders = files([
|
||||
'gskgpucolorize.glsl',
|
||||
'gskgpucolormatrix.glsl',
|
||||
'gskgpuconicgradient.glsl',
|
||||
'gskgpucrossfade.glsl',
|
||||
'gskgpulineargradient.glsl',
|
||||
'gskgpumask.glsl',
|
||||
'gskgpuradialgradient.glsl',
|
||||
|
@ -84,6 +84,7 @@ gsk_private_sources = files([
|
||||
'gpu/gskgpucolormatrixop.c',
|
||||
'gpu/gskgpucolorop.c',
|
||||
'gpu/gskgpuconicgradientop.c',
|
||||
'gpu/gskgpucrossfadeop.c',
|
||||
'gpu/gskgpudescriptors.c',
|
||||
'gpu/gskgpudownloadop.c',
|
||||
'gpu/gskgpudevice.c',
|
||||
|
Loading…
Reference in New Issue
Block a user