'vulkan/gskvulkancommandpool.c',
'vulkan/gskvulkancrossfadeop.c',
'vulkan/gskvulkanglyphcache.c',
+ 'vulkan/gskvulkanglyphop.c',
'vulkan/gskvulkanimage.c',
'vulkan/gskvulkaninsetshadowop.c',
'vulkan/gskvulkanlineargradientop.c',
--- /dev/null
+#include "config.h"
+
+#include "gskvulkanglyphopprivate.h"
+
+#include "vulkan/resources/glyph.vert.h"
+
+typedef struct _GskVulkanGlyphOp GskVulkanGlyphOp;
+
+struct _GskVulkanGlyphOp
+{
+ GskVulkanOp op;
+
+ GskVulkanImage *image;
+ graphene_rect_t rect;
+ graphene_rect_t tex_rect;
+ GdkRGBA color;
+
+ guint32 image_descriptor;
+ gsize vertex_offset;
+};
+
+static void
+gsk_vulkan_glyph_op_finish (GskVulkanOp *op)
+{
+ GskVulkanGlyphOp *self = (GskVulkanGlyphOp *) op;
+
+ g_object_unref (self->image);
+}
+
+static void
+gsk_vulkan_glyph_op_upload (GskVulkanOp *op,
+ GskVulkanRenderPass *pass,
+ GskVulkanRender *render,
+ GskVulkanUploader *uploader)
+{
+}
+
+static inline gsize
+round_up (gsize number, gsize divisor)
+{
+ return (number + divisor - 1) / divisor * divisor;
+}
+
+static gsize
+gsk_vulkan_glyph_op_count_vertex_data (GskVulkanOp *op,
+ gsize n_bytes)
+{
+ GskVulkanGlyphOp *self = (GskVulkanGlyphOp *) op;
+ gsize vertex_stride;
+
+ vertex_stride = gsk_vulkan_glyph_info.pVertexBindingDescriptions[0].stride;
+ n_bytes = round_up (n_bytes, vertex_stride);
+ self->vertex_offset = n_bytes;
+ n_bytes += vertex_stride;
+ return n_bytes;
+}
+
+static void
+gsk_vulkan_glyph_op_collect_vertex_data (GskVulkanOp *op,
+ GskVulkanRenderPass *pass,
+ GskVulkanRender *render,
+ guchar *data)
+{
+ GskVulkanGlyphOp *self = (GskVulkanGlyphOp *) op;
+ GskVulkanGlyphInstance *instance = (GskVulkanGlyphInstance *) (data + self->vertex_offset);
+
+ gsk_vulkan_rect_to_float (&self->rect, instance->rect);
+ gsk_vulkan_rect_to_float (&self->tex_rect, instance->tex_rect);
+ instance->tex_id = self->image_descriptor;
+ gsk_vulkan_rgba_to_float (&self->color, instance->color);
+}
+
+static void
+gsk_vulkan_glyph_op_reserve_descriptor_sets (GskVulkanOp *op,
+ GskVulkanRender *render)
+{
+ GskVulkanGlyphOp *self = (GskVulkanGlyphOp *) op;
+
+ self->image_descriptor = gsk_vulkan_render_get_image_descriptor (render, self->image, GSK_VULKAN_SAMPLER_DEFAULT);
+}
+
+static VkPipeline
+gsk_vulkan_glyph_op_get_pipeline (GskVulkanOp *op)
+{
+ return VK_NULL_HANDLE;
+}
+
+static void
+gsk_vulkan_glyph_op_command (GskVulkanOp *op,
+ GskVulkanRender *render,
+ VkPipelineLayout pipeline_layout,
+ VkCommandBuffer command_buffer)
+{
+ GskVulkanGlyphOp *self = (GskVulkanGlyphOp *) op;
+
+ vkCmdDraw (command_buffer,
+ 6, 1,
+ 0, self->vertex_offset / gsk_vulkan_glyph_info.pVertexBindingDescriptions[0].stride);
+}
+
+static const GskVulkanOpClass GSK_VULKAN_GLYPH_OP_CLASS = {
+ GSK_VULKAN_OP_SIZE (GskVulkanGlyphOp),
+ "glyph",
+ &gsk_vulkan_glyph_info,
+ gsk_vulkan_glyph_op_finish,
+ gsk_vulkan_glyph_op_upload,
+ gsk_vulkan_glyph_op_count_vertex_data,
+ gsk_vulkan_glyph_op_collect_vertex_data,
+ gsk_vulkan_glyph_op_reserve_descriptor_sets,
+ gsk_vulkan_glyph_op_get_pipeline,
+ gsk_vulkan_glyph_op_command
+};
+
+void
+gsk_vulkan_glyph_op (GskVulkanRenderPass *render_pass,
+ const char *clip_type,
+ GskVulkanImage *image,
+ const graphene_rect_t *rect,
+ const graphene_point_t *offset,
+ const graphene_rect_t *tex_rect,
+ const GdkRGBA *color)
+{
+ GskVulkanGlyphOp *self;
+
+ self = (GskVulkanGlyphOp *) gsk_vulkan_op_alloc (render_pass, &GSK_VULKAN_GLYPH_OP_CLASS);
+
+ ((GskVulkanOp *) self)->clip_type = g_intern_string (clip_type);
+ self->image = g_object_ref (image);
+ graphene_rect_offset_r (rect, offset->x, offset->y, &self->rect);
+ gsk_vulkan_normalize_tex_coords (&self->tex_rect, rect, tex_rect);
+ self->color = *color;
+}
--- /dev/null
+#pragma once
+
+#include "gskvulkanopprivate.h"
+
+G_BEGIN_DECLS
+
+void gsk_vulkan_glyph_op (GskVulkanRenderPass *render_pass,
+ const char *clip_type,
+ GskVulkanImage *image,
+ const graphene_rect_t *rect,
+ const graphene_point_t *offset,
+ const graphene_rect_t *tex_rect,
+ const GdkRGBA *color);
+
+
+G_END_DECLS
+
#include "gskvulkancoloropprivate.h"
#include "gskvulkancolortextpipelineprivate.h"
#include "gskvulkancrossfadeopprivate.h"
+#include "gskvulkanglyphopprivate.h"
#include "gskvulkaninsetshadowopprivate.h"
#include "gskvulkanlineargradientopprivate.h"
#include "gskvulkanopprivate.h"
return TRUE;
}
+static inline gboolean
+gsk_vulkan_render_pass_add_mask_node (GskVulkanRenderPass *self,
+ GskVulkanRender *render,
+ const GskVulkanParseState *state,
+ GskRenderNode *node)
+{
+ GskVulkanImage *mask_image;
+ graphene_rect_t mask_tex_rect;
+ GskRenderNode *source, *mask;
+ GskMaskMode mode;
+
+ mode = gsk_mask_node_get_mask_mode (node);
+ source = gsk_mask_node_get_source (node);
+ mask = gsk_mask_node_get_mask (node);
+ mask_image = gsk_vulkan_render_pass_get_node_as_image (self,
+ render,
+ state,
+ mask,
+ &mask_tex_rect);
+ if (mask_image == NULL)
+ {
+ if (mode == GSK_MASK_MODE_INVERTED_ALPHA)
+ gsk_vulkan_render_pass_add_node (self, render, state, source);
+
+ return TRUE;
+ }
+
+ /* Use the glyph shader as an optimization */
+ if (mode == GSK_MASK_MODE_ALPHA &&
+ gsk_render_node_get_node_type (source) == GSK_COLOR_NODE)
+ {
+ graphene_rect_t bounds;
+ if (graphene_rect_intersection (&source->bounds, &mask->bounds, &bounds))
+ gsk_vulkan_glyph_op (self,
+ gsk_vulkan_clip_get_clip_type (&state->clip, &state->offset, &bounds),
+ mask_image,
+ &bounds,
+ &state->offset,
+ &mask_tex_rect,
+ gsk_color_node_get_color (source));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static inline gboolean
gsk_vulkan_render_pass_add_debug_node (GskVulkanRenderPass *self,
GskVulkanRender *render,
[GSK_DEBUG_NODE] = gsk_vulkan_render_pass_add_debug_node,
[GSK_GL_SHADER_NODE] = NULL,
[GSK_TEXTURE_SCALE_NODE] = gsk_vulkan_render_pass_add_texture_scale_node,
- [GSK_MASK_NODE] = NULL,
+ [GSK_MASK_NODE] = gsk_vulkan_render_pass_add_mask_node,
};
static void
--- /dev/null
+#version 450
+
+#include "common.frag.glsl"
+#include "clip.frag.glsl"
+#include "rect.frag.glsl"
+
+layout(location = 0) in vec2 inPos;
+layout(location = 1) in flat Rect inRect;
+layout(location = 2) in vec2 inTexCoord;
+layout(location = 3) in flat uint inTexId;
+layout(location = 4) in flat vec4 inColor;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ float alpha = inColor.a * rect_coverage (inRect, inPos);
+ alpha *= texture(get_sampler (inTexId), inTexCoord).a;
+ color = clip_scaled (inPos, vec4(inColor.rgb, 1) * alpha);
+}
--- /dev/null
+#version 450
+
+#include "common.vert.glsl"
+#include "rect.vert.glsl"
+
+layout(location = 0) in vec4 inRect;
+layout(location = 1) in vec4 inTexRect;
+layout(location = 2) in vec4 inColor;
+layout(location = 3) in uint inTexId;
+
+layout(location = 0) out vec2 outPos;
+layout(location = 1) out flat Rect outRect;
+layout(location = 2) out vec2 outTexCoord;
+layout(location = 3) out flat uint outTexId;
+layout(location = 4) out flat vec4 outColor;
+
+void main() {
+ Rect r = rect_from_gsk (inRect);
+ vec2 pos = set_position_from_rect (r);
+
+ outPos = pos;
+ outRect = r;
+ outTexCoord = scale_tex_coord (pos, r, inTexRect);
+ outTexId = inTexId;
+ outColor = inColor;
+}
'color.frag',
'color-matrix.frag',
'cross-fade.frag',
+ 'glyph.frag',
'inset-shadow.frag',
'linear.frag',
'mask.frag',
'color.vert',
'color-matrix.vert',
'cross-fade.vert',
+ 'glyph.vert',
'inset-shadow.vert',
'linear.vert',
'mask.vert',