if have_vulkan
gsk_private_sources += files([
- 'vulkan/gskvulkanblendmodepipeline.c',
+ 'vulkan/gskvulkanblendmodeop.c',
'vulkan/gskvulkanblurpipeline.c',
'vulkan/gskvulkanborderpipeline.c',
'vulkan/gskvulkanboxshadowpipeline.c',
--- /dev/null
+#include "config.h"
+
+#include "gskvulkanblendmodeopprivate.h"
+
+#include "vulkan/resources/blend-mode.vert.h"
+
+typedef struct _GskVulkanBlendModeOp GskVulkanBlendModeOp;
+
+struct _GskVulkanBlendModeOp
+{
+ GskVulkanOp op;
+
+ graphene_rect_t bounds;
+ GskBlendMode blend_mode;
+
+ struct {
+ GskVulkanImage *image;
+ graphene_rect_t rect;
+ graphene_rect_t tex_rect;
+ guint32 image_descriptor;
+ } top, bottom;
+
+ gsize vertex_offset;
+};
+
+static void
+gsk_vulkan_blend_mode_op_finish (GskVulkanOp *op)
+{
+ GskVulkanBlendModeOp *self = (GskVulkanBlendModeOp *) op;
+
+ g_object_unref (self->top.image);
+ g_object_unref (self->bottom.image);
+}
+
+static void
+gsk_vulkan_blend_mode_op_upload (GskVulkanOp *op,
+ GskVulkanRenderPass *pass,
+ GskVulkanRender *render,
+ GskVulkanUploader *uploader,
+ const graphene_rect_t *clip,
+ const graphene_vec2_t *scale)
+{
+}
+
+static inline gsize
+round_up (gsize number, gsize divisor)
+{
+ return (number + divisor - 1) / divisor * divisor;
+}
+
+static gsize
+gsk_vulkan_blend_mode_op_count_vertex_data (GskVulkanOp *op,
+ gsize n_bytes)
+{
+ GskVulkanBlendModeOp *self = (GskVulkanBlendModeOp *) op;
+ gsize vertex_stride;
+
+ vertex_stride = gsk_vulkan_blend_mode_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_blend_mode_op_collect_vertex_data (GskVulkanOp *op,
+ GskVulkanRenderPass *pass,
+ GskVulkanRender *render,
+ guchar *data)
+{
+ GskVulkanBlendModeOp *self = (GskVulkanBlendModeOp *) op;
+ GskVulkanBlendModeInstance *instance = (GskVulkanBlendModeInstance *) (data + self->vertex_offset);
+
+ gsk_vulkan_rect_to_float (&self->bounds, instance->rect);
+ gsk_vulkan_rect_to_float (&self->top.rect, instance->top_rect);
+ gsk_vulkan_rect_to_float (&self->bottom.rect, instance->bottom_rect);
+ gsk_vulkan_rect_to_float (&self->top.tex_rect, instance->top_tex_rect);
+ gsk_vulkan_rect_to_float (&self->bottom.tex_rect, instance->bottom_tex_rect);
+
+ instance->top_tex_id = self->top.image_descriptor;
+ instance->bottom_tex_id = self->bottom.image_descriptor;
+ instance->blend_mode = self->blend_mode;
+}
+
+static void
+gsk_vulkan_blend_mode_op_reserve_descriptor_sets (GskVulkanOp *op,
+ GskVulkanRender *render)
+{
+ GskVulkanBlendModeOp *self = (GskVulkanBlendModeOp *) op;
+
+ self->top.image_descriptor = gsk_vulkan_render_get_image_descriptor (render,
+ self->top.image,
+ GSK_VULKAN_SAMPLER_DEFAULT);
+ self->bottom.image_descriptor = gsk_vulkan_render_get_image_descriptor (render,
+ self->bottom.image,
+ GSK_VULKAN_SAMPLER_DEFAULT);
+}
+
+static VkPipeline
+gsk_vulkan_blend_mode_op_get_pipeline (GskVulkanOp *op)
+{
+ return VK_NULL_HANDLE;
+}
+
+static void
+gsk_vulkan_blend_mode_op_command (GskVulkanOp *op,
+ GskVulkanRender *render,
+ VkPipelineLayout pipeline_layout,
+ VkCommandBuffer command_buffer)
+{
+ GskVulkanBlendModeOp *self = (GskVulkanBlendModeOp *) op;
+
+ vkCmdDraw (command_buffer,
+ 6, 1,
+ 0, self->vertex_offset / gsk_vulkan_blend_mode_info.pVertexBindingDescriptions[0].stride);
+}
+
+static const GskVulkanShaderOpClass GSK_VULKAN_BLEND_MODE_OP_CLASS = {
+ GSK_VULKAN_OP_SIZE (GskVulkanBlendModeOp),
+ "blend-mode",
+ &gsk_vulkan_blend_mode_info,
+ gsk_vulkan_blend_mode_op_finish,
+ gsk_vulkan_blend_mode_op_upload,
+ gsk_vulkan_blend_mode_op_count_vertex_data,
+ gsk_vulkan_blend_mode_op_collect_vertex_data,
+ gsk_vulkan_blend_mode_op_reserve_descriptor_sets,
+ gsk_vulkan_blend_mode_op_get_pipeline,
+ gsk_vulkan_blend_mode_op_command
+};
+
+void
+gsk_vulkan_blend_mode_op (GskVulkanRenderPass *render_pass,
+ const char *clip_type,
+ const graphene_rect_t *bounds,
+ const graphene_point_t *offset,
+ GskBlendMode blend_mode,
+ GskVulkanImage *top_image,
+ const graphene_rect_t *top_rect,
+ const graphene_rect_t *top_tex_rect,
+ GskVulkanImage *bottom_image,
+ const graphene_rect_t *bottom_rect,
+ const graphene_rect_t *bottom_tex_rect)
+{
+ GskVulkanBlendModeOp *self;
+
+ self = (GskVulkanBlendModeOp *) gsk_vulkan_op_alloc (render_pass, &GSK_VULKAN_BLEND_MODE_OP_CLASS);
+
+ ((GskVulkanOp *) self)->clip_type = g_intern_string (clip_type);
+ graphene_rect_offset_r (bounds, offset->x, offset->y, &self->bounds);
+ self->blend_mode = blend_mode;
+
+ self->top.image = g_object_ref (top_image);
+ graphene_rect_offset_r (top_rect, offset->x, offset->y, &self->top.rect);
+ gsk_vulkan_normalize_tex_coords (&self->top.tex_rect, bounds, top_tex_rect);
+
+ self->bottom.image = g_object_ref (bottom_image);
+ graphene_rect_offset_r (bottom_rect, offset->x, offset->y, &self->bottom.rect);
+ gsk_vulkan_normalize_tex_coords (&self->bottom.tex_rect, bounds, bottom_tex_rect);
+}
--- /dev/null
+#pragma once
+
+#include "gskvulkanopprivate.h"
+
+G_BEGIN_DECLS
+
+void gsk_vulkan_blend_mode_op (GskVulkanRenderPass *render_pass,
+ const char *clip_type,
+ const graphene_rect_t *bounds,
+ const graphene_point_t *offset,
+ GskBlendMode blend_mode,
+ GskVulkanImage *top_image,
+ const graphene_rect_t *top_rect,
+ const graphene_rect_t *top_tex_rect,
+ GskVulkanImage *bottom_image,
+ const graphene_rect_t *bottom_rect,
+ const graphene_rect_t *bottom_tex_rect);
+
+
+G_END_DECLS
+
+++ /dev/null
-#include "config.h"
-
-#include "gskvulkanblendmodepipelineprivate.h"
-
-#include "vulkan/resources/blend-mode.vert.h"
-
-struct _GskVulkanBlendModePipeline
-{
- GObject parent_instance;
-};
-
-typedef struct _GskVulkanBlendModeInstance GskVulkanBlendModeInstance;
-
-G_DEFINE_TYPE (GskVulkanBlendModePipeline, gsk_vulkan_blend_mode_pipeline, GSK_TYPE_VULKAN_PIPELINE)
-
-static const VkPipelineVertexInputStateCreateInfo *
-gsk_vulkan_blend_mode_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
-{
- return &gsk_vulkan_blend_mode_info;
-}
-
-static void
-gsk_vulkan_blend_mode_pipeline_finalize (GObject *gobject)
-{
- //GskVulkanBlendModePipeline *self = GSK_VULKAN_BLUR_PIPELINE (gobject);
-
- G_OBJECT_CLASS (gsk_vulkan_blend_mode_pipeline_parent_class)->finalize (gobject);
-}
-
-static void
-gsk_vulkan_blend_mode_pipeline_class_init (GskVulkanBlendModePipelineClass *klass)
-{
- GskVulkanPipelineClass *pipeline_class = GSK_VULKAN_PIPELINE_CLASS (klass);
-
- G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_blend_mode_pipeline_finalize;
-
- pipeline_class->get_input_state_create_info = gsk_vulkan_blend_mode_pipeline_get_input_state_create_info;
-}
-
-static void
-gsk_vulkan_blend_mode_pipeline_init (GskVulkanBlendModePipeline *self)
-{
-}
-
-GskVulkanPipeline *
-gsk_vulkan_blend_mode_pipeline_new (GdkVulkanContext *context,
- VkPipelineLayout layout,
- const char *shader_name,
- VkRenderPass render_pass)
-{
- return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_BLEND_MODE_PIPELINE, context, layout, shader_name, render_pass);
-}
-
-void
-gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GskVulkanBlendModePipeline *pipeline,
- guchar *data,
- guint32 top_tex_id,
- guint32 bottom_tex_id,
- const graphene_point_t *offset,
- const graphene_rect_t *bounds,
- const graphene_rect_t *top_bounds,
- const graphene_rect_t *bottom_bounds,
- const graphene_rect_t *top_tex_rect,
- const graphene_rect_t *bottom_tex_rect,
- GskBlendMode blend_mode)
-{
- GskVulkanBlendModeInstance *instance = (GskVulkanBlendModeInstance *) data;
-
- instance->rect[0] = bounds->origin.x + offset->x;
- instance->rect[1] = bounds->origin.y + offset->y;
- instance->rect[2] = bounds->size.width;
- instance->rect[3] = bounds->size.height;
-
- instance->top_rect[0] = top_bounds->origin.x + offset->x;
- instance->top_rect[1] = top_bounds->origin.y + offset->y;
- instance->top_rect[2] = top_bounds->size.width;
- instance->top_rect[3] = top_bounds->size.height;
-
- instance->bottom_rect[0] = bottom_bounds->origin.x + offset->x;
- instance->bottom_rect[1] = bottom_bounds->origin.y + offset->y;
- instance->bottom_rect[2] = bottom_bounds->size.width;
- instance->bottom_rect[3] = bottom_bounds->size.height;
-
- instance->top_tex_rect[0] = top_tex_rect->origin.x;
- instance->top_tex_rect[1] = top_tex_rect->origin.y;
- instance->top_tex_rect[2] = top_tex_rect->size.width;
- instance->top_tex_rect[3] = top_tex_rect->size.height;
-
- instance->bottom_tex_rect[0] = bottom_tex_rect->origin.x;
- instance->bottom_tex_rect[1] = bottom_tex_rect->origin.y;
- instance->bottom_tex_rect[2] = bottom_tex_rect->size.width;
- instance->bottom_tex_rect[3] = bottom_tex_rect->size.height;
-
- instance->top_tex_id = top_tex_id;
- instance->bottom_tex_id = bottom_tex_id;
- instance->blend_mode = blend_mode;
-}
-
-gsize
-gsk_vulkan_blend_mode_pipeline_draw (GskVulkanBlendModePipeline *pipeline,
- VkCommandBuffer command_buffer,
- gsize offset,
- gsize n_commands)
-{
- vkCmdDraw (command_buffer,
- 6, n_commands,
- 0, offset);
-
- return n_commands;
-}
+++ /dev/null
-#pragma once
-
-#include <graphene.h>
-
-#include "gskvulkanpipelineprivate.h"
-#include "gskenums.h"
-
-G_BEGIN_DECLS
-
-typedef struct _GskVulkanBlendModePipelineLayout GskVulkanBlendModePipelineLayout;
-
-#define GSK_TYPE_VULKAN_BLEND_MODE_PIPELINE (gsk_vulkan_blend_mode_pipeline_get_type ())
-
-G_DECLARE_FINAL_TYPE (GskVulkanBlendModePipeline, gsk_vulkan_blend_mode_pipeline, GSK, VULKAN_BLEND_MODE_PIPELINE, GskVulkanPipeline)
-
-GskVulkanPipeline * gsk_vulkan_blend_mode_pipeline_new (GdkVulkanContext *context,
- VkPipelineLayout layout,
- const char *shader_name,
- VkRenderPass render_pass);
-
-void gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GskVulkanBlendModePipeline *pipeline,
- guchar *data,
- guint32 top_tex_id,
- guint32 bottom_tex_id,
- const graphene_point_t *offset,
- const graphene_rect_t *bounds,
- const graphene_rect_t *top_bounds,
- const graphene_rect_t *bottom_bounds,
- const graphene_rect_t *top_tex_rect,
- const graphene_rect_t *bottom_tex_rect,
- GskBlendMode blend_mode);
-gsize gsk_vulkan_blend_mode_pipeline_draw (GskVulkanBlendModePipeline *pipeline,
- VkCommandBuffer command_buffer,
- gsize offset,
- gsize n_commands);
-
-
-G_END_DECLS
-
#include "gskvulkanpipelineprivate.h"
#include "gskvulkanrenderpassprivate.h"
-#include "gskvulkanblendmodepipelineprivate.h"
#include "gskvulkanblurpipelineprivate.h"
#include "gskvulkanborderpipelineprivate.h"
#include "gskvulkanboxshadowpipelineprivate.h"
{ "texture", 1, gsk_vulkan_color_text_pipeline_new },
{ "texture-clip", 1, gsk_vulkan_color_text_pipeline_new },
{ "texture-clip-rounded", 1, gsk_vulkan_color_text_pipeline_new },
- { "blend-mode", 2, gsk_vulkan_blend_mode_pipeline_new },
- { "blend-mode-clip", 2, gsk_vulkan_blend_mode_pipeline_new },
- { "blend-mode-clip-rounded", 2, gsk_vulkan_blend_mode_pipeline_new },
};
g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);
#include "gskrendererprivate.h"
#include "gskroundedrectprivate.h"
#include "gsktransform.h"
-#include "gskvulkanblendmodepipelineprivate.h"
+#include "gskvulkanblendmodeopprivate.h"
#include "gskvulkanblurpipelineprivate.h"
#include "gskvulkanborderpipelineprivate.h"
#include "gskvulkanboxshadowpipelineprivate.h"
GSK_VULKAN_OP_BORDER,
GSK_VULKAN_OP_INSET_SHADOW,
GSK_VULKAN_OP_OUTSET_SHADOW,
- GSK_VULKAN_OP_BLEND_MODE,
/* GskVulkanOpText */
GSK_VULKAN_OP_TEXT,
GSK_VULKAN_OP_COLOR_TEXT,
const GskVulkanParseState *state,
GskRenderNode *node)
{
- GskVulkanPipelineType pipeline_type;
- GskVulkanOpRender op = {
- .type = GSK_VULKAN_OP_BLEND_MODE,
- .node = node,
- .offset = state->offset,
- };
+ GskRenderNode *top_child, *bottom_child;
+ GskVulkanImage *top_image, *bottom_image;
+ graphene_rect_t top_tex_rect, bottom_tex_rect;
- if (gsk_vulkan_clip_contains_rect (&state->clip, &state->offset, &node->bounds))
- pipeline_type = GSK_VULKAN_PIPELINE_BLEND_MODE;
- else if (state->clip.type == GSK_VULKAN_CLIP_RECT)
- pipeline_type = GSK_VULKAN_PIPELINE_BLEND_MODE_CLIP;
- else
- pipeline_type = GSK_VULKAN_PIPELINE_BLEND_MODE_CLIP_ROUNDED;
+ top_child = gsk_blend_node_get_top_child (node);
+ top_image = gsk_vulkan_render_pass_get_node_as_image (self,
+ render,
+ state,
+ top_child,
+ &top_tex_rect);
+ bottom_child = gsk_blend_node_get_bottom_child (node);
+ bottom_image = gsk_vulkan_render_pass_get_node_as_image (self,
+ render,
+ state,
+ bottom_child,
+ &bottom_tex_rect);
+ if (top_image == NULL)
+ {
+ if (bottom_image == NULL)
+ return TRUE;
- op.pipeline = gsk_vulkan_render_pass_get_pipeline (self, render, pipeline_type);
- gsk_vulkan_render_pass_add_op (self, (GskVulkanOp *) &op);
+ top_image = bottom_image;
+ top_tex_rect = *graphene_rect_zero ();
+ }
+ else if (bottom_image == NULL)
+ {
+ bottom_image = top_image;
+ bottom_tex_rect = *graphene_rect_zero ();
+ }
+
+ gsk_vulkan_blend_mode_op (self,
+ gsk_vulkan_clip_get_clip_type (&state->clip, &state->offset, &node->bounds),
+ &node->bounds,
+ &state->offset,
+ gsk_blend_node_get_blend_mode (node),
+ top_image,
+ &top_child->bounds,
+ &top_tex_rect,
+ bottom_image,
+ &bottom_child->bounds,
+ &bottom_tex_rect);
return TRUE;
}
}
break;
- case GSK_VULKAN_OP_BLEND_MODE:
- {
- GskRenderNode *top = gsk_blend_node_get_top_child (op->render.node);
- GskRenderNode *bottom = gsk_blend_node_get_bottom_child (op->render.node);
- graphene_rect_t tex_bounds;
-
- op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
- render,
- uploader,
- top,
- scale,
- clip,
- &op->render.offset,
- &tex_bounds);
- gsk_vulkan_normalize_tex_coords (&op->render.source_rect, &op->render.node->bounds, &tex_bounds);
-
- op->render.source2 = gsk_vulkan_render_pass_get_node_as_texture (self,
- render,
- uploader,
- bottom,
- scale,
- clip,
- &op->render.offset,
- &tex_bounds);
- gsk_vulkan_normalize_tex_coords (&op->render.source2_rect, &op->render.node->bounds, &tex_bounds);
- if (!op->render.source)
- {
- op->render.source = op->render.source2;
- op->render.source_rect = *graphene_rect_zero();
- }
- if (!op->render.source2)
- {
- op->render.source2 = op->render.source;
- op->render.source2_rect = *graphene_rect_zero();
- }
- }
- break;
-
default:
g_assert_not_reached ();
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
case GSK_VULKAN_OP_BORDER:
case GSK_VULKAN_OP_INSET_SHADOW:
case GSK_VULKAN_OP_OUTSET_SHADOW:
- case GSK_VULKAN_OP_BLEND_MODE:
vertex_stride = gsk_vulkan_pipeline_get_vertex_stride (op->render.pipeline);
n_bytes = round_up (n_bytes, vertex_stride);
op->render.vertex_offset = n_bytes;
gsk_outset_shadow_node_get_blur_radius (op->render.node));
break;
- case GSK_VULKAN_OP_BLEND_MODE:
- gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GSK_VULKAN_BLEND_MODE_PIPELINE (op->render.pipeline),
- data + op->render.vertex_offset,
- op->render.image_descriptor,
- op->render.image_descriptor2,
- &op->render.offset,
- &op->render.node->bounds,
- &gsk_blend_node_get_top_child (op->render.node)->bounds,
- &gsk_blend_node_get_bottom_child (op->render.node)->bounds,
- &op->render.source_rect,
- &op->render.source2_rect,
- gsk_blend_node_get_blend_mode (op->render.node));
- break;
-
default:
g_assert_not_reached ();
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
GSK_VULKAN_SAMPLER_DEFAULT);
break;
- case GSK_VULKAN_OP_BLEND_MODE:
- if (op->render.source && op->render.source2)
- {
- op->render.image_descriptor = gsk_vulkan_render_get_image_descriptor (render,
- op->render.source,
- GSK_VULKAN_SAMPLER_DEFAULT);
- op->render.image_descriptor2 = gsk_vulkan_render_get_image_descriptor (render,
- op->render.source2,
- GSK_VULKAN_SAMPLER_DEFAULT);
- }
- break;
-
case GSK_VULKAN_OP_LINEAR_GRADIENT:
{
gsize n_stops = gsk_linear_gradient_node_get_n_color_stops (op->render.node);
case GSK_VULKAN_OP_BORDER:
case GSK_VULKAN_OP_INSET_SHADOW:
case GSK_VULKAN_OP_OUTSET_SHADOW:
- case GSK_VULKAN_OP_BLEND_MODE:
return gsk_vulkan_pipeline_get_pipeline (op->render.pipeline);
case GSK_VULKAN_OP_TEXT:
&op->constants.clip);
break;
- case GSK_VULKAN_OP_BLEND_MODE:
- if (!op->render.source || !op->render.source2)
- break;
- gsk_vulkan_blend_mode_pipeline_draw (GSK_VULKAN_BLEND_MODE_PIPELINE (op->render.pipeline),
- command_buffer,
- op->render.vertex_offset / gsk_vulkan_pipeline_get_vertex_stride (op->render.pipeline),
- 1);
- break;
-
default:
g_assert_not_reached ();
break;
GSK_VULKAN_PIPELINE_COLOR_TEXT,
GSK_VULKAN_PIPELINE_COLOR_TEXT_CLIP,
GSK_VULKAN_PIPELINE_COLOR_TEXT_CLIP_ROUNDED,
- GSK_VULKAN_PIPELINE_BLEND_MODE,
- GSK_VULKAN_PIPELINE_BLEND_MODE_CLIP,
- GSK_VULKAN_PIPELINE_BLEND_MODE_CLIP_ROUNDED,
/* add more */
GSK_VULKAN_N_PIPELINES
} GskVulkanPipelineType;