mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-19 21:40:22 +00:00
gpu: Add colorize shader
... and use it for glyphs. The name is a slight variation of the "coloring" name from the GL renderer. The functionality is exactly what the "glyph" shader from the Vulkan renderer does.
This commit is contained in:
parent
d1d1af1a62
commit
5ab8fde0bc
102
gsk/gpu/gskgpucolorizeop.c
Normal file
102
gsk/gpu/gskgpucolorizeop.c
Normal file
@ -0,0 +1,102 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "gskgpucolorizeopprivate.h"
|
||||
|
||||
#include "gskgpuframeprivate.h"
|
||||
#include "gskgpuprintprivate.h"
|
||||
#include "gskrectprivate.h"
|
||||
|
||||
#include "gpu/shaders/gskgpucolorizeinstance.h"
|
||||
|
||||
typedef struct _GskGpuColorizeOp GskGpuColorizeOp;
|
||||
|
||||
struct _GskGpuColorizeOp
|
||||
{
|
||||
GskGpuShaderOp op;
|
||||
|
||||
GskGpuShaderImage image;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_colorize_op_finish (GskGpuOp *op)
|
||||
{
|
||||
GskGpuColorizeOp *self = (GskGpuColorizeOp *) op;
|
||||
|
||||
g_object_unref (self->image.image);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_colorize_op_print (GskGpuOp *op,
|
||||
GskGpuFrame *frame,
|
||||
GString *string,
|
||||
guint indent)
|
||||
{
|
||||
GskGpuColorizeOp *self = (GskGpuColorizeOp *) op;
|
||||
GskGpuShaderOp *shader = (GskGpuShaderOp *) op;
|
||||
GskGpuColorizeInstance *instance;
|
||||
|
||||
instance = (GskGpuColorizeInstance *) gsk_gpu_frame_get_vertex_data (frame, shader->vertex_offset);
|
||||
|
||||
gsk_gpu_print_op (string, indent, "colorize");
|
||||
gsk_gpu_print_rect (string, instance->rect);
|
||||
gsk_gpu_print_image (string, self->image.image);
|
||||
gsk_gpu_print_rgba (string, instance->color);
|
||||
gsk_gpu_print_newline (string);
|
||||
}
|
||||
|
||||
static const GskGpuShaderImage *
|
||||
gsk_gpu_colorize_op_get_images (GskGpuShaderOp *op,
|
||||
gsize *n_images)
|
||||
{
|
||||
GskGpuColorizeOp *self = (GskGpuColorizeOp *) op;
|
||||
|
||||
*n_images = 1;
|
||||
|
||||
return &self->image;
|
||||
}
|
||||
|
||||
static const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = {
|
||||
{
|
||||
GSK_GPU_OP_SIZE (GskGpuColorizeOp),
|
||||
GSK_GPU_STAGE_SHADER,
|
||||
gsk_gpu_colorize_op_finish,
|
||||
gsk_gpu_colorize_op_print,
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
gsk_gpu_shader_op_vk_command,
|
||||
#endif
|
||||
gsk_gpu_shader_op_gl_command
|
||||
},
|
||||
"gskgpucolorize",
|
||||
sizeof (GskGpuColorizeInstance),
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
&gsk_gpu_colorize_info,
|
||||
#endif
|
||||
gsk_gpu_colorize_op_get_images,
|
||||
gsk_gpu_colorize_setup_vao
|
||||
};
|
||||
|
||||
void
|
||||
gsk_gpu_colorize_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuImage *image,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
GskGpuColorizeInstance *instance;
|
||||
GskGpuColorizeOp *self;
|
||||
|
||||
self = (GskGpuColorizeOp *) gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_COLORIZE_OP_CLASS,
|
||||
clip,
|
||||
&instance);
|
||||
|
||||
gsk_gpu_rect_to_float (rect, offset, instance->rect);
|
||||
gsk_gpu_rect_to_float (tex_rect, offset, instance->tex_rect);
|
||||
self->image.image = g_object_ref (image);
|
||||
self->image.sampler = GSK_GPU_SAMPLER_DEFAULT;
|
||||
self->image.descriptor = gsk_gpu_frame_get_image_descriptor (frame, image, GSK_GPU_SAMPLER_DEFAULT);
|
||||
instance->tex_id = self->image.descriptor;
|
||||
gsk_gpu_rgba_to_float (color, instance->color);
|
||||
}
|
19
gsk/gpu/gskgpucolorizeopprivate.h
Normal file
19
gsk/gpu/gskgpucolorizeopprivate.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "gskgpushaderopprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_colorize_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuImage *image,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const GdkRGBA *color);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "gskgpuborderopprivate.h"
|
||||
#include "gskgpuclipprivate.h"
|
||||
#include "gskgpucolorizeopprivate.h"
|
||||
#include "gskgpudeviceprivate.h"
|
||||
#include "gskgpuframeprivate.h"
|
||||
#include "gskgpuglobalsopprivate.h"
|
||||
@ -985,6 +986,72 @@ gsk_gpu_node_processor_create_conic_gradient_pattern (GskGpuPatternWriter *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
GskGpuDevice *device;
|
||||
const PangoGlyphInfo *glyphs;
|
||||
PangoFont *font;
|
||||
graphene_point_t offset;
|
||||
guint i, num_glyphs;
|
||||
float scale, inv_scale;
|
||||
|
||||
device = gsk_gpu_frame_get_device (self->frame);
|
||||
num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
font = gsk_text_node_get_font (node);
|
||||
offset = *gsk_text_node_get_offset (node);
|
||||
offset.x += self->offset.x;
|
||||
offset.y += self->offset.y;
|
||||
|
||||
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
|
||||
inv_scale = 1.f / scale;
|
||||
|
||||
for (i = 0; i < num_glyphs; i++)
|
||||
{
|
||||
GskGpuImage *image;
|
||||
graphene_rect_t glyph_bounds, glyph_tex_rect;
|
||||
graphene_point_t glyph_offset;
|
||||
|
||||
image = gsk_gpu_device_lookup_glyph_image (device,
|
||||
self->frame,
|
||||
font,
|
||||
glyphs[i].glyph,
|
||||
0,
|
||||
scale,
|
||||
&glyph_bounds,
|
||||
&glyph_offset);
|
||||
|
||||
graphene_rect_scale (&glyph_bounds, inv_scale, inv_scale, &glyph_bounds);
|
||||
glyph_offset = GRAPHENE_POINT_INIT (offset.x - glyph_offset.x * inv_scale + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
|
||||
offset.y - glyph_offset.y * inv_scale + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
|
||||
glyph_tex_rect = GRAPHENE_RECT_INIT (
|
||||
0, 0,
|
||||
gsk_gpu_image_get_width (image) * inv_scale,
|
||||
gsk_gpu_image_get_height (image) * inv_scale
|
||||
);
|
||||
if (gsk_text_node_has_color_glyphs (node))
|
||||
gsk_gpu_texture_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
|
||||
image,
|
||||
GSK_GPU_SAMPLER_DEFAULT,
|
||||
&glyph_bounds,
|
||||
&glyph_offset,
|
||||
&glyph_tex_rect);
|
||||
else
|
||||
gsk_gpu_colorize_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
|
||||
image,
|
||||
&glyph_bounds,
|
||||
&glyph_offset,
|
||||
&glyph_tex_rect,
|
||||
gsk_text_node_get_color (node));
|
||||
|
||||
offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
|
||||
GskRenderNode *node)
|
||||
@ -1247,7 +1314,7 @@ static const struct
|
||||
},
|
||||
[GSK_TEXT_NODE] = {
|
||||
0,
|
||||
NULL,
|
||||
gsk_gpu_node_processor_add_glyph_node,
|
||||
gsk_gpu_node_processor_create_glyph_pattern,
|
||||
},
|
||||
[GSK_BLUR_NODE] = {
|
||||
|
47
gsk/gpu/shaders/gskgpucolorize.glsl
Normal file
47
gsk/gpu/shaders/gskgpucolorize.glsl
Normal file
@ -0,0 +1,47 @@
|
||||
#include "common.glsl"
|
||||
|
||||
PASS(0) vec2 _pos;
|
||||
PASS_FLAT(1) Rect _rect;
|
||||
PASS_FLAT(2) vec4 _color;
|
||||
PASS(3) vec2 _tex_coord;
|
||||
PASS_FLAT(4) uint _tex_id;
|
||||
|
||||
|
||||
|
||||
#ifdef GSK_VERTEX_SHADER
|
||||
|
||||
IN(0) vec4 in_rect;
|
||||
IN(1) vec4 in_color;
|
||||
IN(2) vec4 in_tex_rect;
|
||||
IN(3) uint in_tex_id;
|
||||
|
||||
void
|
||||
run (out vec2 pos)
|
||||
{
|
||||
Rect r = rect_from_gsk (in_rect);
|
||||
|
||||
pos = rect_get_position (r);
|
||||
|
||||
_pos = pos;
|
||||
_rect = r;
|
||||
_color = color_premultiply (in_color);
|
||||
_tex_coord = rect_get_coord (rect_from_gsk (in_tex_rect), pos);
|
||||
_tex_id = in_tex_id;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef GSK_FRAGMENT_SHADER
|
||||
|
||||
void
|
||||
run (out vec4 color,
|
||||
out vec2 position)
|
||||
{
|
||||
float alpha = texture (gsk_get_texture (_tex_id), _tex_coord).a * rect_coverage (_rect, _pos);
|
||||
color = _color * alpha;
|
||||
position = _pos;
|
||||
}
|
||||
|
||||
#endif
|
@ -13,6 +13,7 @@ gsk_private_gpu_include_shaders = files([
|
||||
|
||||
gsk_private_gpu_shaders = files([
|
||||
'gskgpuborder.glsl',
|
||||
'gskgpucolorize.glsl',
|
||||
'gskgputexture.glsl',
|
||||
'gskgpuuber.glsl',
|
||||
])
|
||||
|
@ -76,6 +76,7 @@ gsk_private_sources = files([
|
||||
'gpu/gskgpubuffer.c',
|
||||
'gpu/gskgpubufferwriter.c',
|
||||
'gpu/gskgpuclip.c',
|
||||
'gpu/gskgpucolorizeop.c',
|
||||
'gpu/gskgpudownloadop.c',
|
||||
'gpu/gskgpudevice.c',
|
||||
'gpu/gskgpuframe.c',
|
||||
|
Loading…
Reference in New Issue
Block a user