2016-12-08 12:26:36 +00:00
# include "config.h"
# include "gskvulkanrenderpassprivate.h"
2016-12-23 23:52:07 +00:00
# include "gskdebugprivate.h"
2017-09-26 01:02:21 +00:00
# include "gskprofilerprivate.h"
2016-12-23 20:36:17 +00:00
# include "gskrendernodeprivate.h"
# include "gskrenderer.h"
2017-09-26 01:02:21 +00:00
# include "gskrendererprivate.h"
2016-12-23 20:36:17 +00:00
# include "gskroundedrectprivate.h"
2019-03-01 05:35:55 +00:00
# include "gsktransform.h"
2017-09-23 05:59:50 +00:00
# include "gskvulkanblendmodepipelineprivate.h"
2017-09-03 13:54:47 +00:00
# include "gskvulkanblurpipelineprivate.h"
2017-01-10 13:59:20 +00:00
# include "gskvulkanborderpipelineprivate.h"
2017-01-18 03:07:09 +00:00
# include "gskvulkanboxshadowpipelineprivate.h"
2016-12-23 20:36:17 +00:00
# include "gskvulkanclipprivate.h"
2016-12-18 01:18:01 +00:00
# include "gskvulkancolorpipelineprivate.h"
2017-09-01 20:58:42 +00:00
# include "gskvulkancolortextpipelineprivate.h"
2017-09-22 18:20:57 +00:00
# include "gskvulkancrossfadepipelineprivate.h"
2016-12-30 05:46:34 +00:00
# include "gskvulkaneffectpipelineprivate.h"
2016-12-26 16:11:13 +00:00
# include "gskvulkanlineargradientpipelineprivate.h"
2017-09-01 20:58:42 +00:00
# include "gskvulkantextpipelineprivate.h"
2017-09-30 02:24:53 +00:00
# include "gskvulkantexturepipelineprivate.h"
2016-12-08 12:26:36 +00:00
# include "gskvulkanimageprivate.h"
2016-12-14 06:21:21 +00:00
# include "gskvulkanpushconstantsprivate.h"
2016-12-09 06:23:04 +00:00
# include "gskvulkanrendererprivate.h"
2017-09-01 20:58:42 +00:00
# include "gskprivate.h"
# include <cairo-ft.h>
2016-12-08 12:26:36 +00:00
2017-09-28 00:56:01 +00:00
# define ORTHO_NEAR_PLANE -10000
# define ORTHO_FAR_PLANE 10000
2016-12-14 06:34:18 +00:00
typedef union _GskVulkanOp GskVulkanOp ;
typedef struct _GskVulkanOpRender GskVulkanOpRender ;
2017-09-19 22:53:32 +00:00
typedef struct _GskVulkanOpText GskVulkanOpText ;
2016-12-14 06:34:18 +00:00
typedef struct _GskVulkanOpPushConstants GskVulkanOpPushConstants ;
2016-12-08 12:26:36 +00:00
typedef enum {
2016-12-14 06:34:18 +00:00
/* GskVulkanOpRender */
2016-12-09 04:59:19 +00:00
GSK_VULKAN_OP_FALLBACK ,
2016-12-23 20:36:17 +00:00
GSK_VULKAN_OP_FALLBACK_CLIP ,
GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP ,
2016-12-12 23:11:06 +00:00
GSK_VULKAN_OP_TEXTURE ,
2016-12-14 08:40:15 +00:00
GSK_VULKAN_OP_COLOR ,
2016-12-26 16:11:13 +00:00
GSK_VULKAN_OP_LINEAR_GRADIENT ,
2016-12-30 05:46:34 +00:00
GSK_VULKAN_OP_OPACITY ,
2017-09-03 13:54:47 +00:00
GSK_VULKAN_OP_BLUR ,
2016-12-31 13:14:26 +00:00
GSK_VULKAN_OP_COLOR_MATRIX ,
2017-01-10 13:59:20 +00:00
GSK_VULKAN_OP_BORDER ,
2017-01-18 03:07:09 +00:00
GSK_VULKAN_OP_INSET_SHADOW ,
GSK_VULKAN_OP_OUTSET_SHADOW ,
2017-09-30 02:41:00 +00:00
GSK_VULKAN_OP_REPEAT ,
2017-09-23 13:47:05 +00:00
GSK_VULKAN_OP_CROSS_FADE ,
GSK_VULKAN_OP_BLEND_MODE ,
2017-09-22 18:20:57 +00:00
/* GskVulkanOpText */
GSK_VULKAN_OP_TEXT ,
GSK_VULKAN_OP_COLOR_TEXT ,
2016-12-14 06:34:18 +00:00
/* GskVulkanOpPushConstants */
2017-09-22 18:20:57 +00:00
GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS ,
2016-12-08 12:26:36 +00:00
} GskVulkanOpType ;
2017-09-23 13:47:05 +00:00
/* render ops with 0, 1 or 2 sources */
2016-12-14 06:34:18 +00:00
struct _GskVulkanOpRender
2016-12-08 12:26:36 +00:00
{
GskVulkanOpType type ;
GskRenderNode * node ; /* node that's the source of this op */
2016-12-14 08:40:15 +00:00
GskVulkanPipeline * pipeline ; /* pipeline to use */
2016-12-23 20:36:17 +00:00
GskRoundedRect clip ; /* clip rect (or random memory if not relevant) */
2016-12-08 12:26:36 +00:00
GskVulkanImage * source ; /* source image to render */
2017-09-23 13:47:05 +00:00
GskVulkanImage * source2 ; /* second source image to render (if relevant) */
2016-12-08 12:26:36 +00:00
gsize vertex_offset ; /* offset into vertex buffer */
gsize vertex_count ; /* number of vertices */
2016-12-09 01:55:47 +00:00
gsize descriptor_set_index ; /* index into descriptor sets array for the right descriptor set to bind */
2017-09-23 13:47:05 +00:00
gsize descriptor_set_index2 ; /* descriptor index for the second source (if relevant) */
2017-10-01 23:17:39 +00:00
graphene_rect_t source_rect ; /* area that source maps to */
graphene_rect_t source2_rect ; /* area that source2 maps to */
2016-12-08 12:26:36 +00:00
} ;
2017-09-19 22:53:32 +00:00
struct _GskVulkanOpText
{
GskVulkanOpType type ;
GskRenderNode * node ; /* node that's the source of this op */
GskVulkanPipeline * pipeline ; /* pipeline to use */
GskRoundedRect clip ; /* clip rect (or random memory if not relevant) */
GskVulkanImage * source ; /* source image to render */
gsize vertex_offset ; /* offset into vertex buffer */
gsize vertex_count ; /* number of vertices */
gsize descriptor_set_index ; /* index into descriptor sets array for the right descriptor set to bind */
2017-09-20 03:32:07 +00:00
guint texture_index ; /* index of the texture in the glyph cache */
guint start_glyph ; /* the first glyph in nodes glyphstring that we render */
guint num_glyphs ; /* number of *non-empty* glyphs (== instances) we render */
2017-10-28 17:13:31 +00:00
float scale ;
2017-09-19 22:53:32 +00:00
} ;
2016-12-14 06:34:18 +00:00
struct _GskVulkanOpPushConstants
{
GskVulkanOpType type ;
GskRenderNode * node ; /* node that's the source of this op */
GskVulkanPushConstants constants ; /* new constants to push */
} ;
union _GskVulkanOp
{
GskVulkanOpType type ;
GskVulkanOpRender render ;
2017-09-19 22:53:32 +00:00
GskVulkanOpText text ;
2017-09-22 18:20:57 +00:00
GskVulkanOpPushConstants constants ;
2016-12-14 06:34:18 +00:00
} ;
2016-12-08 12:26:36 +00:00
struct _GskVulkanRenderPass
{
GdkVulkanContext * vulkan ;
GArray * render_ops ;
2017-09-25 13:25:29 +00:00
2017-09-28 00:56:01 +00:00
GskVulkanImage * target ;
int scale_factor ;
graphene_rect_t viewport ;
cairo_region_t * clip ;
2017-09-29 19:45:37 +00:00
graphene_matrix_t mv ;
graphene_matrix_t p ;
2017-09-28 00:56:01 +00:00
VkRenderPass render_pass ;
VkSemaphore signal_semaphore ;
GArray * wait_semaphores ;
GskVulkanBuffer * vertex_data ;
2017-09-26 01:02:21 +00:00
GQuark fallback_pixels ;
2017-09-30 14:39:04 +00:00
GQuark texture_pixels ;
2016-12-08 12:26:36 +00:00
} ;
GskVulkanRenderPass *
2017-09-28 00:56:01 +00:00
gsk_vulkan_render_pass_new ( GdkVulkanContext * context ,
GskVulkanImage * target ,
int scale_factor ,
2017-09-29 19:45:37 +00:00
graphene_matrix_t * mv ,
2017-09-28 00:56:01 +00:00
graphene_rect_t * viewport ,
cairo_region_t * clip ,
VkSemaphore signal_semaphore )
2016-12-08 12:26:36 +00:00
{
GskVulkanRenderPass * self ;
2017-09-28 00:56:01 +00:00
VkImageLayout final_layout ;
2016-12-08 12:26:36 +00:00
self = g_slice_new0 ( GskVulkanRenderPass ) ;
self - > vulkan = g_object_ref ( context ) ;
2016-12-14 06:34:18 +00:00
self - > render_ops = g_array_new ( FALSE , FALSE , sizeof ( GskVulkanOp ) ) ;
2017-09-28 00:56:01 +00:00
self - > target = g_object_ref ( target ) ;
self - > scale_factor = scale_factor ;
self - > clip = cairo_region_copy ( clip ) ;
2017-09-29 19:45:37 +00:00
self - > viewport = * viewport ;
2017-09-28 00:56:01 +00:00
2017-09-29 19:45:37 +00:00
self - > mv = * mv ;
graphene_matrix_init_ortho ( & self - > p ,
2017-09-28 00:56:01 +00:00
viewport - > origin . x , viewport - > origin . x + viewport - > size . width ,
viewport - > origin . y , viewport - > origin . y + viewport - > size . height ,
ORTHO_NEAR_PLANE ,
ORTHO_FAR_PLANE ) ;
if ( signal_semaphore ! = VK_NULL_HANDLE ) // this is a dependent pass
final_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ;
else
final_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ;
GSK_VK_CHECK ( vkCreateRenderPass , gdk_vulkan_context_get_device ( self - > vulkan ) ,
& ( VkRenderPassCreateInfo ) {
. sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO ,
. attachmentCount = 1 ,
. pAttachments = ( VkAttachmentDescription [ ] ) {
{
. format = gdk_vulkan_context_get_image_format ( self - > vulkan ) ,
. samples = VK_SAMPLE_COUNT_1_BIT ,
. loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR ,
. storeOp = VK_ATTACHMENT_STORE_OP_STORE ,
. initialLayout = VK_IMAGE_LAYOUT_UNDEFINED ,
. finalLayout = final_layout
}
} ,
. subpassCount = 1 ,
. pSubpasses = ( VkSubpassDescription [ ] ) {
{
. pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS ,
. inputAttachmentCount = 0 ,
. colorAttachmentCount = 1 ,
. pColorAttachments = ( VkAttachmentReference [ ] ) {
{
. attachment = 0 ,
. layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
}
} ,
. pResolveAttachments = ( VkAttachmentReference [ ] ) {
{
. attachment = VK_ATTACHMENT_UNUSED ,
. layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
}
} ,
. pDepthStencilAttachment = NULL ,
}
} ,
. dependencyCount = 0
} ,
NULL ,
& self - > render_pass ) ;
self - > signal_semaphore = signal_semaphore ;
self - > wait_semaphores = g_array_new ( FALSE , FALSE , sizeof ( VkSemaphore ) ) ;
self - > vertex_data = NULL ;
2017-09-26 01:02:21 +00:00
# ifdef G_ENABLE_DEBUG
self - > fallback_pixels = g_quark_from_static_string ( " fallback-pixels " ) ;
2017-09-30 14:39:04 +00:00
self - > texture_pixels = g_quark_from_static_string ( " texture-pixels " ) ;
2017-09-26 01:02:21 +00:00
# endif
2016-12-08 12:26:36 +00:00
return self ;
}
void
gsk_vulkan_render_pass_free ( GskVulkanRenderPass * self )
{
g_array_unref ( self - > render_ops ) ;
g_object_unref ( self - > vulkan ) ;
2017-09-28 00:56:01 +00:00
g_object_unref ( self - > target ) ;
cairo_region_destroy ( self - > clip ) ;
vkDestroyRenderPass ( gdk_vulkan_context_get_device ( self - > vulkan ) ,
self - > render_pass ,
NULL ) ;
if ( self - > vertex_data )
gsk_vulkan_buffer_free ( self - > vertex_data ) ;
if ( self - > signal_semaphore ! = VK_NULL_HANDLE )
vkDestroySemaphore ( gdk_vulkan_context_get_device ( self - > vulkan ) ,
self - > signal_semaphore ,
NULL ) ;
g_array_unref ( self - > wait_semaphores ) ;
2016-12-08 12:26:36 +00:00
g_slice_free ( GskVulkanRenderPass , self ) ;
}
2017-09-01 20:58:42 +00:00
static gboolean
2017-10-20 07:12:19 +00:00
font_has_color_glyphs ( const PangoFont * font )
2017-09-01 20:58:42 +00:00
{
cairo_scaled_font_t * scaled_font ;
gboolean has_color = FALSE ;
scaled_font = pango_cairo_font_get_scaled_font ( ( PangoCairoFont * ) font ) ;
if ( cairo_scaled_font_get_type ( scaled_font ) = = CAIRO_FONT_TYPE_FT )
{
FT_Face ft_face = cairo_ft_scaled_font_lock_face ( scaled_font ) ;
has_color = ( FT_HAS_COLOR ( ft_face ) ! = 0 ) ;
cairo_ft_scaled_font_unlock_face ( scaled_font ) ;
}
return has_color ;
}
2016-12-23 23:52:07 +00:00
# define FALLBACK(...) G_STMT_START { \
2018-01-14 14:52:52 +00:00
GSK_RENDERER_NOTE ( gsk_vulkan_render_get_renderer ( render ) , FALLBACK , g_message ( __VA_ARGS__ ) ) ; \
2016-12-23 23:52:07 +00:00
goto fallback ; \
} G_STMT_END
2017-04-26 16:27:24 +00:00
static void
2016-12-14 06:21:21 +00:00
gsk_vulkan_render_pass_add_node ( GskVulkanRenderPass * self ,
GskVulkanRender * render ,
const GskVulkanPushConstants * constants ,
GskRenderNode * node )
2016-12-08 12:26:36 +00:00
{
2016-12-14 06:34:18 +00:00
GskVulkanOp op = {
2016-12-08 12:26:36 +00:00
. type = GSK_VULKAN_OP_FALLBACK ,
2016-12-14 06:34:18 +00:00
. render . node = node
2016-12-08 12:26:36 +00:00
} ;
2016-12-24 05:16:54 +00:00
GskVulkanPipelineType pipeline_type ;
2016-12-08 12:26:36 +00:00
2016-12-11 01:33:58 +00:00
switch ( gsk_render_node_get_node_type ( node ) )
2016-12-09 04:59:19 +00:00
{
2016-12-11 01:33:58 +00:00
case GSK_NOT_A_RENDER_NODE :
g_assert_not_reached ( ) ;
2016-12-23 20:36:17 +00:00
return ;
2016-12-30 05:46:34 +00:00
case GSK_SHADOW_NODE :
2016-12-13 03:20:04 +00:00
default :
2018-01-14 14:52:52 +00:00
FALLBACK ( " Unsupported node '%s' " , node - > node_class - > type_name ) ;
2016-12-13 03:20:04 +00:00
2017-09-30 02:41:00 +00:00
case GSK_REPEAT_NODE :
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Repeat nodes can't deal with clip type %u " , constants - > clip . type ) ;
2017-09-30 02:41:00 +00:00
op . type = GSK_VULKAN_OP_REPEAT ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
2017-09-23 05:59:50 +00:00
case GSK_BLEND_NODE :
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_BLEND_MODE ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_BLEND_MODE_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_BLEND_MODE_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Blend nodes can't deal with clip type %u " , constants - > clip . type ) ;
2017-09-23 05:59:50 +00:00
op . type = GSK_VULKAN_OP_BLEND_MODE ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
2017-09-22 18:20:57 +00:00
case GSK_CROSS_FADE_NODE :
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_CROSS_FADE ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_CROSS_FADE_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_CROSS_FADE_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Cross fade nodes can't deal with clip type %u " , constants - > clip . type ) ;
2017-09-22 18:20:57 +00:00
op . type = GSK_VULKAN_OP_CROSS_FADE ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
2017-01-18 03:07:09 +00:00
case GSK_INSET_SHADOW_NODE :
if ( gsk_inset_shadow_node_get_blur_radius ( node ) > 0 )
2018-01-14 14:52:52 +00:00
FALLBACK ( " Blur support not implemented for inset shadows " ) ;
2017-01-18 03:07:09 +00:00
else if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_INSET_SHADOW ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_INSET_SHADOW_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_INSET_SHADOW_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Inset shadow nodes can't deal with clip type %u " , constants - > clip . type ) ;
2017-01-18 03:07:09 +00:00
op . type = GSK_VULKAN_OP_INSET_SHADOW ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
case GSK_OUTSET_SHADOW_NODE :
if ( gsk_outset_shadow_node_get_blur_radius ( node ) > 0 )
2018-01-14 14:52:52 +00:00
FALLBACK ( " Blur support not implemented for outset shadows " ) ;
2017-01-18 03:07:09 +00:00
else if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_OUTSET_SHADOW ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_OUTSET_SHADOW_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_OUTSET_SHADOW_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Outset shadow nodes can't deal with clip type %u " , constants - > clip . type ) ;
2017-01-18 03:07:09 +00:00
op . type = GSK_VULKAN_OP_OUTSET_SHADOW ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
2016-12-11 01:33:58 +00:00
case GSK_CAIRO_NODE :
2017-10-20 06:52:02 +00:00
if ( gsk_cairo_node_peek_surface ( node ) = = NULL )
2016-12-23 20:36:17 +00:00
return ;
2018-03-24 15:41:59 +00:00
/* We're using recording surfaces, so drawing them to an image
* surface and uploading them is the right thing .
* But that ' s exactly what the fallback code does .
*/
goto fallback ;
2016-12-11 01:33:58 +00:00
2017-09-01 20:58:42 +00:00
case GSK_TEXT_NODE :
2017-09-19 22:53:32 +00:00
{
2017-10-20 07:12:19 +00:00
const PangoFont * font = gsk_text_node_peek_font ( node ) ;
2017-10-27 21:13:40 +00:00
const PangoGlyphInfo * glyphs = gsk_text_node_peek_glyphs ( node ) ;
guint num_glyphs = gsk_text_node_get_num_glyphs ( node ) ;
2017-09-19 22:53:32 +00:00
int i ;
2017-09-20 03:32:07 +00:00
guint count ;
2017-09-19 22:53:32 +00:00
guint texture_index ;
2019-07-25 21:50:31 +00:00
gint x_position ;
2017-09-19 22:53:32 +00:00
GskVulkanRenderer * renderer = GSK_VULKAN_RENDERER ( gsk_vulkan_render_get_renderer ( render ) ) ;
if ( font_has_color_glyphs ( font ) )
{
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_TEXT ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_TEXT_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_TEXT_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Text nodes can't deal with clip type %u " , constants - > clip . type ) ;
2017-09-19 22:53:32 +00:00
op . type = GSK_VULKAN_OP_COLOR_TEXT ;
}
else
{
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_TEXT ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_TEXT_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_TEXT_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Text nodes can't deal with clip type %u " , constants - > clip . type ) ;
2017-09-19 22:53:32 +00:00
op . type = GSK_VULKAN_OP_TEXT ;
}
op . text . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
2017-09-11 01:55:22 +00:00
2017-09-20 03:32:07 +00:00
op . text . start_glyph = 0 ;
op . text . texture_index = G_MAXUINT ;
2017-10-28 18:38:21 +00:00
op . text . scale = self - > scale_factor ;
2017-09-20 03:32:07 +00:00
2019-07-25 21:50:31 +00:00
x_position = 0 ;
2017-10-27 21:13:40 +00:00
for ( i = 0 , count = 0 ; i < num_glyphs ; i + + )
2017-09-19 22:53:32 +00:00
{
2017-10-27 21:13:40 +00:00
const PangoGlyphInfo * gi = & glyphs [ i ] ;
2017-09-20 03:32:07 +00:00
2019-07-25 21:50:31 +00:00
texture_index = gsk_vulkan_renderer_cache_glyph ( renderer ,
( PangoFont * ) font ,
gi - > glyph ,
x_position + gi - > geometry . x_offset ,
gi - > geometry . y_offset ,
op . text . scale ) ;
2018-01-06 01:30:14 +00:00
if ( op . text . texture_index = = G_MAXUINT )
op . text . texture_index = texture_index ;
if ( texture_index ! = op . text . texture_index )
2017-09-20 03:32:07 +00:00
{
2018-01-06 01:30:14 +00:00
op . text . num_glyphs = count ;
g_array_append_val ( self - > render_ops , op ) ;
count = 1 ;
op . text . start_glyph = i ;
op . text . texture_index = texture_index ;
2017-09-20 03:32:07 +00:00
}
2018-01-06 01:30:14 +00:00
else
count + + ;
2019-07-25 21:50:31 +00:00
x_position + = gi - > geometry . width ;
2017-09-20 03:32:07 +00:00
}
2017-09-19 22:53:32 +00:00
2017-09-20 03:32:07 +00:00
if ( op . text . texture_index ! = G_MAXUINT & & count ! = 0 )
{
op . text . num_glyphs = count ;
2017-09-19 22:53:32 +00:00
g_array_append_val ( self - > render_ops , op ) ;
}
2017-09-20 03:32:07 +00:00
2017-09-19 22:53:32 +00:00
return ;
}
2017-09-01 20:58:42 +00:00
2017-11-04 15:03:03 +00:00
case GSK_TEXTURE_NODE :
2017-01-01 22:47:53 +00:00
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
2017-09-30 02:24:53 +00:00
pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE ;
2017-01-01 22:47:53 +00:00
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
2017-09-30 02:24:53 +00:00
pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP ;
2017-01-01 22:47:53 +00:00
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
2017-09-30 02:24:53 +00:00
pipeline_type = GSK_VULKAN_PIPELINE_TEXTURE_CLIP_ROUNDED ;
2017-01-01 22:47:53 +00:00
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Texture nodes can't deal with clip type %u " , constants - > clip . type ) ;
2016-12-09 04:59:19 +00:00
op . type = GSK_VULKAN_OP_TEXTURE ;
2017-01-01 22:47:53 +00:00
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
2016-12-14 08:40:15 +00:00
g_array_append_val ( self - > render_ops , op ) ;
2016-12-23 20:36:17 +00:00
return ;
2016-12-14 08:40:15 +00:00
case GSK_COLOR_NODE :
2016-12-24 05:16:54 +00:00
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_COLOR ;
2016-12-25 05:01:54 +00:00
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP ;
2016-12-24 05:16:54 +00:00
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Color nodes can't deal with clip type %u " , constants - > clip . type ) ;
2016-12-14 08:40:15 +00:00
op . type = GSK_VULKAN_OP_COLOR ;
2016-12-24 05:16:54 +00:00
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
2016-12-09 04:59:19 +00:00
g_array_append_val ( self - > render_ops , op ) ;
2016-12-23 20:36:17 +00:00
return ;
2016-12-11 01:33:58 +00:00
2016-12-26 16:11:13 +00:00
case GSK_LINEAR_GRADIENT_NODE :
case GSK_REPEATING_LINEAR_GRADIENT_NODE :
if ( gsk_linear_gradient_node_get_n_color_stops ( node ) > GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS )
2018-01-14 14:52:52 +00:00
FALLBACK ( " Linear gradient with %zu color stops, hardcoded limit is %u " ,
2016-12-26 16:11:13 +00:00
gsk_linear_gradient_node_get_n_color_stops ( node ) ,
GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS ) ;
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_LINEAR_GRADIENT_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Linear gradient nodes can't deal with clip type %u " , constants - > clip . type ) ;
2016-12-26 16:11:13 +00:00
op . type = GSK_VULKAN_OP_LINEAR_GRADIENT ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
2016-12-30 05:46:34 +00:00
case GSK_OPACITY_NODE :
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
2016-12-31 12:24:21 +00:00
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX ;
2016-12-30 05:46:34 +00:00
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
2016-12-31 12:24:21 +00:00
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP ;
2016-12-30 05:46:34 +00:00
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
2016-12-31 12:24:21 +00:00
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED ;
2016-12-30 05:46:34 +00:00
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Opacity nodes can't deal with clip type %u " , constants - > clip . type ) ;
2016-12-30 05:46:34 +00:00
op . type = GSK_VULKAN_OP_OPACITY ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
2017-09-03 13:54:47 +00:00
case GSK_BLUR_NODE :
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_BLUR ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_BLUR_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_BLUR_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Blur nodes can't deal with clip type %u " , constants - > clip . type ) ;
2017-09-03 13:54:47 +00:00
op . type = GSK_VULKAN_OP_BLUR ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
2016-12-31 13:14:26 +00:00
case GSK_COLOR_MATRIX_NODE :
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Color matrix nodes can't deal with clip type %u " , constants - > clip . type ) ;
2016-12-31 13:14:26 +00:00
op . type = GSK_VULKAN_OP_COLOR_MATRIX ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
2017-01-10 13:59:20 +00:00
case GSK_BORDER_NODE :
if ( gsk_vulkan_clip_contains_rect ( & constants - > clip , & node - > bounds ) )
pipeline_type = GSK_VULKAN_PIPELINE_BORDER ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_RECT )
pipeline_type = GSK_VULKAN_PIPELINE_BORDER_CLIP ;
else if ( constants - > clip . type = = GSK_VULKAN_CLIP_ROUNDED_CIRCULAR )
pipeline_type = GSK_VULKAN_PIPELINE_BORDER_CLIP_ROUNDED ;
else
2018-01-14 14:52:52 +00:00
FALLBACK ( " Border nodes can't deal with clip type %u " , constants - > clip . type ) ;
2017-01-10 13:59:20 +00:00
op . type = GSK_VULKAN_OP_BORDER ;
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , pipeline_type ) ;
g_array_append_val ( self - > render_ops , op ) ;
return ;
2016-12-11 01:33:58 +00:00
case GSK_CONTAINER_NODE :
2016-12-12 18:30:41 +00:00
{
guint i ;
for ( i = 0 ; i < gsk_container_node_get_n_children ( node ) ; i + + )
{
2016-12-24 03:58:51 +00:00
gsk_vulkan_render_pass_add_node ( self , render , constants , gsk_container_node_get_child ( node , i ) ) ;
2016-12-12 18:30:41 +00:00
}
}
2016-12-23 20:36:17 +00:00
return ;
2018-04-23 22:41:48 +00:00
case GSK_DEBUG_NODE :
gsk_vulkan_render_pass_add_node ( self , render , constants , gsk_debug_node_get_child ( node ) ) ;
return ;
2016-12-12 23:11:06 +00:00
case GSK_TRANSFORM_NODE :
{
2017-10-20 07:31:14 +00:00
graphene_matrix_t transform , mv ;
2016-12-24 03:58:51 +00:00
GskRenderNode * child ;
2016-12-23 20:36:17 +00:00
2016-12-24 03:58:51 +00:00
#if 0
2017-09-29 19:45:37 +00:00
if ( ! gsk_vulkan_clip_contains_rect ( clip , & node - > bounds ) )
2016-12-23 23:52:07 +00:00
FALLBACK ( " Transform nodes can't deal with clip type %u \n " , clip - > type ) ;
2016-12-24 03:58:51 +00:00
# endif
2016-12-12 23:11:06 +00:00
2019-02-20 02:02:23 +00:00
child = gsk_transform_node_get_child ( node ) ;
2019-03-01 05:35:55 +00:00
gsk_transform_to_matrix ( gsk_transform_node_get_transform ( node ) , & transform ) ;
2017-10-20 07:31:14 +00:00
graphene_matrix_init_from_matrix ( & mv , & self - > mv ) ;
2017-09-29 19:45:37 +00:00
graphene_matrix_multiply ( & transform , & mv , & self - > mv ) ;
2016-12-24 03:58:51 +00:00
if ( ! gsk_vulkan_push_constants_transform ( & op . constants . constants , constants , & transform , & child - > bounds ) )
2018-01-14 14:52:52 +00:00
FALLBACK ( " Transform nodes can't deal with clip type %u " , constants - > clip . type ) ;
2016-12-14 06:21:21 +00:00
op . type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS ;
2016-12-12 23:11:06 +00:00
g_array_append_val ( self - > render_ops , op ) ;
2016-12-14 08:40:15 +00:00
2016-12-24 03:58:51 +00:00
gsk_vulkan_render_pass_add_node ( self , render , & op . constants . constants , child ) ;
2016-12-14 06:34:18 +00:00
gsk_vulkan_push_constants_init_copy ( & op . constants . constants , constants ) ;
2017-10-20 07:31:14 +00:00
graphene_matrix_init_from_matrix ( & self - > mv , & mv ) ;
2016-12-12 23:11:06 +00:00
g_array_append_val ( self - > render_ops , op ) ;
}
2016-12-23 20:36:17 +00:00
return ;
case GSK_CLIP_NODE :
{
2016-12-24 03:58:51 +00:00
if ( ! gsk_vulkan_push_constants_intersect_rect ( & op . constants . constants , constants , gsk_clip_node_peek_clip ( node ) ) )
2018-01-14 14:52:52 +00:00
FALLBACK ( " Failed to find intersection between clip of type %u and rectangle " , constants - > clip . type ) ;
2016-12-28 14:37:01 +00:00
if ( op . constants . constants . clip . type = = GSK_VULKAN_CLIP_ALL_CLIPPED )
2016-12-23 20:36:17 +00:00
return ;
2016-12-24 03:58:51 +00:00
op . type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS ;
g_array_append_val ( self - > render_ops , op ) ;
gsk_vulkan_render_pass_add_node ( self , render , & op . constants . constants , gsk_clip_node_get_child ( node ) ) ;
gsk_vulkan_push_constants_init_copy ( & op . constants . constants , constants ) ;
g_array_append_val ( self - > render_ops , op ) ;
2016-12-23 20:36:17 +00:00
}
return ;
case GSK_ROUNDED_CLIP_NODE :
{
2016-12-24 03:58:51 +00:00
if ( ! gsk_vulkan_push_constants_intersect_rounded ( & op . constants . constants ,
constants ,
gsk_rounded_clip_node_peek_clip ( node ) ) )
2018-01-14 14:52:52 +00:00
FALLBACK ( " Failed to find intersection between clip of type %u and rounded rectangle " , constants - > clip . type ) ;
2016-12-28 14:37:01 +00:00
if ( op . constants . constants . clip . type = = GSK_VULKAN_CLIP_ALL_CLIPPED )
2016-12-23 20:36:17 +00:00
return ;
2016-12-24 03:58:51 +00:00
op . type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS ;
g_array_append_val ( self - > render_ops , op ) ;
gsk_vulkan_render_pass_add_node ( self , render , & op . constants . constants , gsk_rounded_clip_node_get_child ( node ) ) ;
gsk_vulkan_push_constants_init_copy ( & op . constants . constants , constants ) ;
g_array_append_val ( self - > render_ops , op ) ;
2016-12-23 20:36:17 +00:00
}
return ;
}
g_assert_not_reached ( ) ;
return ;
fallback :
2016-12-24 03:58:51 +00:00
switch ( constants - > clip . type )
2016-12-23 20:36:17 +00:00
{
case GSK_VULKAN_CLIP_NONE :
op . type = GSK_VULKAN_OP_FALLBACK ;
break ;
case GSK_VULKAN_CLIP_RECT :
op . type = GSK_VULKAN_OP_FALLBACK_CLIP ;
2016-12-24 03:58:51 +00:00
gsk_rounded_rect_init_copy ( & op . render . clip , & constants - > clip . rect ) ;
2016-12-23 20:36:17 +00:00
break ;
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR :
case GSK_VULKAN_CLIP_ROUNDED :
op . type = GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP ;
2016-12-24 03:58:51 +00:00
gsk_rounded_rect_init_copy ( & op . render . clip , & constants - > clip . rect ) ;
2016-12-23 20:36:17 +00:00
break ;
case GSK_VULKAN_CLIP_ALL_CLIPPED :
default :
g_assert_not_reached ( ) ;
return ;
2016-12-09 04:59:19 +00:00
}
2017-09-30 02:24:53 +00:00
op . render . pipeline = gsk_vulkan_render_get_pipeline ( render , GSK_VULKAN_PIPELINE_TEXTURE ) ;
2016-12-23 20:36:17 +00:00
g_array_append_val ( self - > render_ops , op ) ;
2016-12-08 12:26:36 +00:00
}
2016-12-23 23:52:07 +00:00
# undef FALLBACK
2016-12-08 12:26:36 +00:00
2016-12-12 23:11:06 +00:00
void
gsk_vulkan_render_pass_add ( GskVulkanRenderPass * self ,
GskVulkanRender * render ,
GskRenderNode * node )
{
2016-12-14 06:34:18 +00:00
GskVulkanOp op = { 0 , } ;
2017-09-29 19:45:37 +00:00
graphene_matrix_t mvp ;
2016-12-12 23:11:06 +00:00
2017-09-29 19:45:37 +00:00
graphene_matrix_multiply ( & self - > mv , & self - > p , & mvp ) ;
2016-12-14 06:21:21 +00:00
op . type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS ;
2017-09-29 19:45:37 +00:00
gsk_vulkan_push_constants_init ( & op . constants . constants , & mvp , & self - > viewport ) ;
2016-12-12 23:11:06 +00:00
g_array_append_val ( self - > render_ops , op ) ;
2016-12-24 03:58:51 +00:00
gsk_vulkan_render_pass_add_node ( self , render , & op . constants . constants , node ) ;
2016-12-12 23:11:06 +00:00
}
2016-12-30 05:46:34 +00:00
static GskVulkanImage *
2017-10-06 14:01:19 +00:00
gsk_vulkan_render_pass_get_node_as_texture ( GskVulkanRenderPass * self ,
GskVulkanRender * render ,
GskVulkanUploader * uploader ,
GskRenderNode * node ,
const graphene_rect_t * bounds ,
GskVulkanClip * current_clip ,
graphene_rect_t * tex_rect )
2016-12-30 05:46:34 +00:00
{
GskVulkanImage * result ;
cairo_surface_t * surface ;
cairo_t * cr ;
2017-10-06 19:19:42 +00:00
switch ( ( guint ) gsk_render_node_get_node_type ( node ) )
2016-12-31 21:58:15 +00:00
{
2017-11-04 15:03:03 +00:00
case GSK_TEXTURE_NODE :
2017-10-01 23:17:39 +00:00
if ( graphene_rect_equal ( bounds , & node - > bounds ) )
2016-12-31 21:58:15 +00:00
{
2017-09-28 00:56:01 +00:00
result = gsk_vulkan_renderer_ref_texture_image ( GSK_VULKAN_RENDERER ( gsk_vulkan_render_get_renderer ( render ) ) ,
2017-11-04 15:03:03 +00:00
gsk_texture_node_get_texture ( node ) ,
2017-09-28 00:56:01 +00:00
uploader ) ;
gsk_vulkan_render_add_cleanup_image ( render , result ) ;
2017-10-01 23:17:39 +00:00
* tex_rect = GRAPHENE_RECT_INIT ( 0 , 0 , 1 , 1 ) ;
2017-09-28 00:56:01 +00:00
return result ;
2017-10-01 23:17:39 +00:00
}
break ;
2017-09-28 00:56:01 +00:00
2017-10-01 23:17:39 +00:00
case GSK_CAIRO_NODE :
2018-03-24 15:41:59 +00:00
/* We're using recording surfaces, so drawing them to an image
* surface and uploading them is the right thing .
* But that ' s exactly what the fallback code does .
*/
2017-10-01 23:17:39 +00:00
break ;
2016-12-31 21:58:15 +00:00
2017-10-06 19:19:42 +00:00
default :
2017-10-01 23:17:39 +00:00
{
VkSemaphore semaphore ;
graphene_rect_t view ;
cairo_region_t * clip ;
GskVulkanRenderPass * pass ;
graphene_rect_t clipped ;
if ( current_clip )
graphene_rect_intersection ( & current_clip - > rect . bounds , bounds , & clipped ) ;
else
clipped = * bounds ;
2017-09-29 19:45:37 +00:00
2017-10-01 23:17:39 +00:00
if ( clipped . size . width = = 0 | | clipped . size . height = = 0 )
return NULL ;
2017-09-28 00:56:01 +00:00
2017-10-01 23:17:39 +00:00
graphene_matrix_transform_bounds ( & self - > mv , & clipped , & view ) ;
view . origin . x = floor ( view . origin . x ) ;
view . origin . y = floor ( view . origin . y ) ;
view . size . width = ceil ( view . size . width ) ;
view . size . height = ceil ( view . size . height ) ;
result = gsk_vulkan_image_new_for_texture ( self - > vulkan ,
view . size . width ,
view . size . height ) ;
2017-09-28 00:56:01 +00:00
2017-09-30 14:39:04 +00:00
# ifdef G_ENABLE_DEBUG
2017-10-01 23:17:39 +00:00
{
GskProfiler * profiler = gsk_renderer_get_profiler ( gsk_vulkan_render_get_renderer ( render ) ) ;
gsk_profiler_counter_add ( profiler ,
self - > texture_pixels ,
view . size . width * view . size . height ) ;
}
2017-09-30 14:39:04 +00:00
# endif
2017-10-01 23:17:39 +00:00
vkCreateSemaphore ( gdk_vulkan_context_get_device ( self - > vulkan ) ,
& ( VkSemaphoreCreateInfo ) {
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO ,
NULL ,
0
} ,
NULL ,
& semaphore ) ;
g_array_append_val ( self - > wait_semaphores , semaphore ) ;
clip = cairo_region_create_rectangle ( & ( cairo_rectangle_int_t ) {
0 , 0 ,
gsk_vulkan_image_get_width ( result ) ,
gsk_vulkan_image_get_height ( result )
} ) ;
pass = gsk_vulkan_render_pass_new ( self - > vulkan ,
result ,
self - > scale_factor ,
& self - > mv ,
& view ,
clip ,
semaphore ) ;
cairo_region_destroy ( clip ) ;
gsk_vulkan_render_add_render_pass ( render , pass ) ;
gsk_vulkan_render_pass_add ( pass , render , node ) ;
gsk_vulkan_render_add_cleanup_image ( render , result ) ;
/* assuming the unclipped bounds should go to texture coordinates 0..1,
* calculate the coordinates for the clipped texture size
*/
tex_rect - > origin . x = ( bounds - > origin . x - clipped . origin . x ) / clipped . size . width ;
tex_rect - > origin . y = ( bounds - > origin . y - clipped . origin . y ) / clipped . size . height ;
tex_rect - > size . width = bounds - > size . width / clipped . size . width ;
tex_rect - > size . height = bounds - > size . height / clipped . size . height ;
return result ;
}
}
2016-12-31 21:58:15 +00:00
2018-01-14 14:52:52 +00:00
GSK_RENDERER_NOTE ( gsk_vulkan_render_get_renderer ( render ) , FALLBACK , g_message ( " Node as texture not implemented for this case. Using %gx%g fallback surface " ,
2017-01-17 05:38:36 +00:00
ceil ( bounds - > size . width ) ,
2017-09-26 01:02:21 +00:00
ceil ( bounds - > size . height ) ) ) ;
# ifdef G_ENABLE_DEBUG
{
GskProfiler * profiler = gsk_renderer_get_profiler ( gsk_vulkan_render_get_renderer ( render ) ) ;
gsk_profiler_counter_add ( profiler ,
self - > fallback_pixels ,
ceil ( bounds - > size . width ) * ceil ( bounds - > size . height ) ) ;
}
# endif
2017-01-17 05:38:36 +00:00
2016-12-30 05:46:34 +00:00
/* XXX: We could intersect bounds with clip bounds here */
surface = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32 ,
ceil ( bounds - > size . width ) ,
ceil ( bounds - > size . height ) ) ;
cr = cairo_create ( surface ) ;
cairo_translate ( cr , - bounds - > origin . x , - bounds - > origin . y ) ;
gsk_render_node_draw ( node , cr ) ;
cairo_destroy ( cr ) ;
result = gsk_vulkan_image_new_from_data ( uploader ,
cairo_image_surface_get_data ( surface ) ,
cairo_image_surface_get_width ( surface ) ,
cairo_image_surface_get_height ( surface ) ,
cairo_image_surface_get_stride ( surface ) ) ;
cairo_surface_destroy ( surface ) ;
gsk_vulkan_render_add_cleanup_image ( render , result ) ;
2017-10-08 12:44:02 +00:00
tex_rect - > origin . x = ( node - > bounds . origin . x - bounds - > origin . x ) / bounds - > size . width ;
tex_rect - > origin . y = ( node - > bounds . origin . y - bounds - > origin . y ) / bounds - > size . height ;
tex_rect - > size . width = node - > bounds . size . width / bounds - > size . width ;
tex_rect - > size . height = node - > bounds . size . height / bounds - > size . height ;
2017-10-01 23:17:39 +00:00
2016-12-30 05:46:34 +00:00
return result ;
}
2016-12-08 12:26:36 +00:00
static void
2016-12-16 05:10:24 +00:00
gsk_vulkan_render_pass_upload_fallback ( GskVulkanRenderPass * self ,
GskVulkanOpRender * op ,
GskVulkanRender * render ,
2016-12-17 03:22:44 +00:00
GskVulkanUploader * uploader )
2016-12-08 12:26:36 +00:00
{
2016-12-21 10:21:38 +00:00
GskRenderNode * node ;
2016-12-08 12:26:36 +00:00
cairo_surface_t * surface ;
cairo_t * cr ;
2016-12-21 10:21:38 +00:00
node = op - > node ;
2016-12-08 12:26:36 +00:00
2018-01-14 14:52:52 +00:00
GSK_RENDERER_NOTE ( gsk_vulkan_render_get_renderer ( render ) , FALLBACK ,
g_message ( " Upload op=%s, node %s[%p], bounds %gx%g " ,
2017-09-03 15:34:41 +00:00
op - > type = = GSK_VULKAN_OP_FALLBACK_CLIP ? " fallback-clip " :
( op - > type = = GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP ? " fallback-rounded-clip " : " fallback " ) ,
2018-04-24 01:46:44 +00:00
node - > node_class - > type_name , node ,
2017-09-03 15:34:41 +00:00
ceil ( node - > bounds . size . width ) ,
2017-09-26 01:02:21 +00:00
ceil ( node - > bounds . size . height ) ) ) ;
# ifdef G_ENABLE_DEBUG
{
GskProfiler * profiler = gsk_renderer_get_profiler ( gsk_vulkan_render_get_renderer ( render ) ) ;
gsk_profiler_counter_add ( profiler ,
self - > fallback_pixels ,
ceil ( node - > bounds . size . width ) * ceil ( node - > bounds . size . height ) ) ;
}
# endif
2017-09-03 15:34:41 +00:00
2016-12-23 20:36:17 +00:00
/* XXX: We could intersect bounds with clip bounds here */
2016-12-08 12:26:36 +00:00
surface = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32 ,
2017-10-28 18:38:49 +00:00
ceil ( node - > bounds . size . width * self - > scale_factor ) ,
ceil ( node - > bounds . size . height * self - > scale_factor ) ) ;
cairo_surface_set_device_scale ( surface , self - > scale_factor , self - > scale_factor ) ;
2016-12-08 12:26:36 +00:00
cr = cairo_create ( surface ) ;
2016-12-21 10:21:38 +00:00
cairo_translate ( cr , - node - > bounds . origin . x , - node - > bounds . origin . y ) ;
2016-12-23 20:36:17 +00:00
if ( op - > type = = GSK_VULKAN_OP_FALLBACK_CLIP )
{
cairo_rectangle ( cr ,
op - > clip . bounds . origin . x , op - > clip . bounds . origin . y ,
op - > clip . bounds . size . width , op - > clip . bounds . size . height ) ;
cairo_clip ( cr ) ;
}
else if ( op - > type = = GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP )
{
gsk_rounded_rect_path ( & op - > clip , cr ) ;
cairo_clip ( cr ) ;
}
else
{
g_assert ( op - > type = = GSK_VULKAN_OP_FALLBACK ) ;
}
2016-12-21 10:21:38 +00:00
gsk_render_node_draw ( node , cr ) ;
2016-12-08 12:26:36 +00:00
cairo_destroy ( cr ) ;
2016-12-17 03:22:44 +00:00
op - > source = gsk_vulkan_image_new_from_data ( uploader ,
2016-12-08 12:26:36 +00:00
cairo_image_surface_get_data ( surface ) ,
cairo_image_surface_get_width ( surface ) ,
cairo_image_surface_get_height ( surface ) ,
cairo_image_surface_get_stride ( surface ) ) ;
2017-10-01 23:17:39 +00:00
op - > source_rect = GRAPHENE_RECT_INIT ( 0 , 0 , 1 , 1 ) ;
2016-12-08 12:26:36 +00:00
cairo_surface_destroy ( surface ) ;
gsk_vulkan_render_add_cleanup_image ( render , op - > source ) ;
}
void
2016-12-16 05:10:24 +00:00
gsk_vulkan_render_pass_upload ( GskVulkanRenderPass * self ,
GskVulkanRender * render ,
2016-12-17 03:22:44 +00:00
GskVulkanUploader * uploader )
2016-12-08 12:26:36 +00:00
{
2016-12-14 06:34:18 +00:00
GskVulkanOp * op ;
2016-12-08 12:26:36 +00:00
guint i ;
2017-10-06 14:01:19 +00:00
GskVulkanClip * clip = NULL ;
2016-12-08 12:26:36 +00:00
for ( i = 0 ; i < self - > render_ops - > len ; i + + )
{
2016-12-14 06:34:18 +00:00
op = & g_array_index ( self - > render_ops , GskVulkanOp , i ) ;
2016-12-08 12:26:36 +00:00
switch ( op - > type )
{
case GSK_VULKAN_OP_FALLBACK :
2016-12-23 20:36:17 +00:00
case GSK_VULKAN_OP_FALLBACK_CLIP :
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP :
2016-12-17 03:22:44 +00:00
gsk_vulkan_render_pass_upload_fallback ( self , & op - > render , render , uploader ) ;
2016-12-08 12:26:36 +00:00
break ;
2017-09-01 20:58:42 +00:00
case GSK_VULKAN_OP_TEXT :
case GSK_VULKAN_OP_COLOR_TEXT :
{
2017-09-19 22:53:32 +00:00
op - > text . source = gsk_vulkan_renderer_ref_glyph_image ( GSK_VULKAN_RENDERER ( gsk_vulkan_render_get_renderer ( render ) ) ,
uploader ,
op - > text . texture_index ) ;
gsk_vulkan_render_add_cleanup_image ( render , op - > text . source ) ;
2017-09-01 20:58:42 +00:00
}
break ;
2016-12-09 04:59:19 +00:00
case GSK_VULKAN_OP_TEXTURE :
{
2016-12-14 06:34:18 +00:00
op - > render . source = gsk_vulkan_renderer_ref_texture_image ( GSK_VULKAN_RENDERER ( gsk_vulkan_render_get_renderer ( render ) ) ,
2017-11-04 15:03:03 +00:00
gsk_texture_node_get_texture ( op - > render . node ) ,
2016-12-17 03:22:44 +00:00
uploader ) ;
2017-10-01 23:17:39 +00:00
op - > render . source_rect = GRAPHENE_RECT_INIT ( 0 , 0 , 1 , 1 ) ;
2016-12-14 06:34:18 +00:00
gsk_vulkan_render_add_cleanup_image ( render , op - > render . source ) ;
2016-12-09 04:59:19 +00:00
}
break ;
2016-12-30 05:46:34 +00:00
case GSK_VULKAN_OP_OPACITY :
{
GskRenderNode * child = gsk_opacity_node_get_child ( op - > render . node ) ;
2017-09-30 02:41:00 +00:00
op - > render . source = gsk_vulkan_render_pass_get_node_as_texture ( self ,
2016-12-30 05:46:34 +00:00
render ,
uploader ,
child ,
2017-10-01 23:17:39 +00:00
& child - > bounds ,
clip ,
& op - > render . source_rect ) ;
2016-12-30 05:46:34 +00:00
}
break ;
2017-09-30 02:41:00 +00:00
case GSK_VULKAN_OP_REPEAT :
{
GskRenderNode * child = gsk_repeat_node_get_child ( op - > render . node ) ;
2017-10-08 12:44:02 +00:00
const graphene_rect_t * bounds = & op - > render . node - > bounds ;
const graphene_rect_t * child_bounds = gsk_repeat_node_peek_child_bounds ( op - > render . node ) ;
2017-09-30 02:41:00 +00:00
op - > render . source = gsk_vulkan_render_pass_get_node_as_texture ( self ,
render ,
uploader ,
child ,
2017-10-08 12:44:02 +00:00
child_bounds ,
2017-10-01 23:17:39 +00:00
NULL ,
& op - > render . source_rect ) ;
2017-10-08 12:44:02 +00:00
op - > render . source_rect . origin . x = ( bounds - > origin . x - child_bounds - > origin . x ) / child_bounds - > size . width ;
op - > render . source_rect . origin . y = ( bounds - > origin . y - child_bounds - > origin . y ) / child_bounds - > size . height ;
op - > render . source_rect . size . width = bounds - > size . width / child_bounds - > size . width ;
op - > render . source_rect . size . height = bounds - > size . height / child_bounds - > size . height ;
2017-09-30 02:41:00 +00:00
}
break ;
2017-09-03 13:54:47 +00:00
case GSK_VULKAN_OP_BLUR :
{
GskRenderNode * child = gsk_blur_node_get_child ( op - > render . node ) ;
op - > render . source = gsk_vulkan_render_pass_get_node_as_texture ( self ,
render ,
uploader ,
child ,
2017-10-01 23:17:39 +00:00
& child - > bounds ,
clip ,
& op - > render . source_rect ) ;
2017-09-03 13:54:47 +00:00
}
break ;
2016-12-31 13:14:26 +00:00
case GSK_VULKAN_OP_COLOR_MATRIX :
{
GskRenderNode * child = gsk_color_matrix_node_get_child ( op - > render . node ) ;
2017-09-28 00:56:01 +00:00
op - > render . source = gsk_vulkan_render_pass_get_node_as_texture ( self ,
2016-12-31 13:14:26 +00:00
render ,
uploader ,
child ,
2017-10-01 23:17:39 +00:00
& child - > bounds ,
clip ,
& op - > render . source_rect ) ;
2016-12-31 13:14:26 +00:00
}
break ;
2017-09-22 18:20:57 +00:00
case GSK_VULKAN_OP_CROSS_FADE :
{
2017-09-23 13:47:05 +00:00
GskRenderNode * start = gsk_cross_fade_node_get_start_child ( op - > render . node ) ;
GskRenderNode * end = gsk_cross_fade_node_get_end_child ( op - > render . node ) ;
2017-10-08 22:36:57 +00:00
const graphene_rect_t * bounds = & op - > render . node - > bounds ;
2017-09-23 13:47:05 +00:00
op - > render . source = gsk_vulkan_render_pass_get_node_as_texture ( self ,
2017-09-22 18:20:57 +00:00
render ,
uploader ,
2017-09-23 13:47:05 +00:00
start ,
2017-10-08 22:36:57 +00:00
& start - > bounds ,
2017-10-01 23:17:39 +00:00
clip ,
& op - > render . source_rect ) ;
2017-10-08 22:36:57 +00:00
op - > render . source_rect . origin . x = ( bounds - > origin . x - start - > bounds . origin . x ) / start - > bounds . size . width ;
op - > render . source_rect . origin . y = ( bounds - > origin . y - start - > bounds . origin . y ) / start - > bounds . size . height ;
op - > render . source_rect . size . width = bounds - > size . width / start - > bounds . size . width ;
op - > render . source_rect . size . height = bounds - > size . height / start - > bounds . size . height ;
2017-09-23 13:47:05 +00:00
op - > render . source2 = gsk_vulkan_render_pass_get_node_as_texture ( self ,
render ,
uploader ,
end ,
2017-10-08 22:36:57 +00:00
& end - > bounds ,
2017-10-01 23:17:39 +00:00
clip ,
& op - > render . source2_rect ) ;
2017-10-08 22:36:57 +00:00
op - > render . source2_rect . origin . x = ( bounds - > origin . x - end - > bounds . origin . x ) / end - > bounds . size . width ;
op - > render . source2_rect . origin . y = ( bounds - > origin . y - end - > bounds . origin . y ) / end - > bounds . size . height ;
op - > render . source2_rect . size . width = bounds - > size . width / end - > bounds . size . width ;
op - > render . source2_rect . size . height = bounds - > size . height / end - > bounds . size . height ;
2017-09-22 18:20:57 +00:00
}
break ;
2017-09-23 05:59:50 +00:00
case GSK_VULKAN_OP_BLEND_MODE :
{
2017-09-23 13:47:05 +00:00
GskRenderNode * top = gsk_blend_node_get_top_child ( op - > render . node ) ;
GskRenderNode * bottom = gsk_blend_node_get_bottom_child ( op - > render . node ) ;
2017-10-09 00:06:33 +00:00
const graphene_rect_t * bounds = & op - > render . node - > bounds ;
2017-09-23 13:47:05 +00:00
op - > render . source = gsk_vulkan_render_pass_get_node_as_texture ( self ,
2017-09-23 05:59:50 +00:00
render ,
uploader ,
2017-09-23 13:47:05 +00:00
top ,
2017-10-09 00:06:33 +00:00
& top - > bounds ,
2017-10-01 23:17:39 +00:00
clip ,
& op - > render . source_rect ) ;
2017-10-09 00:06:33 +00:00
op - > render . source_rect . origin . x = ( bounds - > origin . x - top - > bounds . origin . x ) / top - > bounds . size . width ;
op - > render . source_rect . origin . y = ( bounds - > origin . y - top - > bounds . origin . y ) / top - > bounds . size . height ;
op - > render . source_rect . size . width = bounds - > size . width / top - > bounds . size . width ;
op - > render . source_rect . size . height = bounds - > size . height / top - > bounds . size . height ;
2017-09-23 13:47:05 +00:00
op - > render . source2 = gsk_vulkan_render_pass_get_node_as_texture ( self ,
render ,
uploader ,
bottom ,
2017-10-09 00:06:33 +00:00
& bottom - > bounds ,
2017-10-01 23:17:39 +00:00
clip ,
& op - > render . source2_rect ) ;
2017-10-09 00:06:33 +00:00
op - > render . source2_rect . origin . x = ( bounds - > origin . x - bottom - > bounds . origin . x ) / bottom - > bounds . size . width ;
op - > render . source2_rect . origin . y = ( bounds - > origin . y - bottom - > bounds . origin . y ) / bottom - > bounds . size . height ;
op - > render . source2_rect . size . width = bounds - > size . width / bottom - > bounds . size . width ;
op - > render . source2_rect . size . height = bounds - > size . height / bottom - > bounds . size . height ;
2017-09-23 05:59:50 +00:00
}
break ;
2017-10-01 23:17:39 +00:00
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS :
clip = & op - > constants . constants . clip ;
break ;
2016-12-08 12:26:36 +00:00
default :
g_assert_not_reached ( ) ;
2016-12-14 08:40:15 +00:00
case GSK_VULKAN_OP_COLOR :
2016-12-26 16:11:13 +00:00
case GSK_VULKAN_OP_LINEAR_GRADIENT :
2017-01-10 13:59:20 +00:00
case GSK_VULKAN_OP_BORDER :
2017-01-18 03:07:09 +00:00
case GSK_VULKAN_OP_INSET_SHADOW :
case GSK_VULKAN_OP_OUTSET_SHADOW :
2016-12-08 12:26:36 +00:00
break ;
}
}
}
2017-09-28 00:56:01 +00:00
static gsize
2016-12-18 00:45:07 +00:00
gsk_vulkan_render_pass_count_vertex_data ( GskVulkanRenderPass * self )
2016-12-08 12:26:36 +00:00
{
2016-12-18 00:45:07 +00:00
GskVulkanOp * op ;
gsize n_bytes ;
guint i ;
2016-12-08 12:26:36 +00:00
2016-12-18 00:45:07 +00:00
n_bytes = 0 ;
for ( i = 0 ; i < self - > render_ops - > len ; i + + )
{
op = & g_array_index ( self - > render_ops , GskVulkanOp , i ) ;
2016-12-08 12:26:36 +00:00
2016-12-18 00:45:07 +00:00
switch ( op - > type )
{
case GSK_VULKAN_OP_FALLBACK :
2016-12-23 20:36:17 +00:00
case GSK_VULKAN_OP_FALLBACK_CLIP :
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP :
2016-12-18 00:45:07 +00:00
case GSK_VULKAN_OP_TEXTURE :
2017-09-30 02:41:00 +00:00
case GSK_VULKAN_OP_REPEAT :
2017-09-30 02:24:53 +00:00
op - > render . vertex_count = gsk_vulkan_texture_pipeline_count_vertex_data ( GSK_VULKAN_TEXTURE_PIPELINE ( op - > render . pipeline ) ) ;
2016-12-18 00:45:07 +00:00
n_bytes + = op - > render . vertex_count ;
break ;
2016-12-08 12:26:36 +00:00
2017-09-01 20:58:42 +00:00
case GSK_VULKAN_OP_TEXT :
2017-09-19 22:53:32 +00:00
op - > text . vertex_count = gsk_vulkan_text_pipeline_count_vertex_data ( GSK_VULKAN_TEXT_PIPELINE ( op - > text . pipeline ) ,
op - > text . num_glyphs ) ;
n_bytes + = op - > text . vertex_count ;
2017-09-01 20:58:42 +00:00
break ;
case GSK_VULKAN_OP_COLOR_TEXT :
2017-09-19 22:53:32 +00:00
op - > text . vertex_count = gsk_vulkan_color_text_pipeline_count_vertex_data ( GSK_VULKAN_COLOR_TEXT_PIPELINE ( op - > render . pipeline ) ,
op - > text . num_glyphs ) ;
n_bytes + = op - > text . vertex_count ;
2017-09-01 20:58:42 +00:00
break ;
2016-12-18 01:18:01 +00:00
case GSK_VULKAN_OP_COLOR :
op - > render . vertex_count = gsk_vulkan_color_pipeline_count_vertex_data ( GSK_VULKAN_COLOR_PIPELINE ( op - > render . pipeline ) ) ;
n_bytes + = op - > render . vertex_count ;
break ;
2016-12-26 16:11:13 +00:00
case GSK_VULKAN_OP_LINEAR_GRADIENT :
op - > render . vertex_count = gsk_vulkan_linear_gradient_pipeline_count_vertex_data ( GSK_VULKAN_LINEAR_GRADIENT_PIPELINE ( op - > render . pipeline ) ) ;
n_bytes + = op - > render . vertex_count ;
break ;
2016-12-30 05:46:34 +00:00
case GSK_VULKAN_OP_OPACITY :
2016-12-31 13:14:26 +00:00
case GSK_VULKAN_OP_COLOR_MATRIX :
2016-12-30 05:46:34 +00:00
op - > render . vertex_count = gsk_vulkan_effect_pipeline_count_vertex_data ( GSK_VULKAN_EFFECT_PIPELINE ( op - > render . pipeline ) ) ;
n_bytes + = op - > render . vertex_count ;
break ;
2017-09-03 13:54:47 +00:00
case GSK_VULKAN_OP_BLUR :
op - > render . vertex_count = gsk_vulkan_blur_pipeline_count_vertex_data ( GSK_VULKAN_BLUR_PIPELINE ( op - > render . pipeline ) ) ;
n_bytes + = op - > render . vertex_count ;
break ;
2017-01-10 13:59:20 +00:00
case GSK_VULKAN_OP_BORDER :
op - > render . vertex_count = gsk_vulkan_border_pipeline_count_vertex_data ( GSK_VULKAN_BORDER_PIPELINE ( op - > render . pipeline ) ) ;
n_bytes + = op - > render . vertex_count ;
break ;
2017-01-18 03:07:09 +00:00
case GSK_VULKAN_OP_INSET_SHADOW :
case GSK_VULKAN_OP_OUTSET_SHADOW :
op - > render . vertex_count = gsk_vulkan_box_shadow_pipeline_count_vertex_data ( GSK_VULKAN_BOX_SHADOW_PIPELINE ( op - > render . pipeline ) ) ;
n_bytes + = op - > render . vertex_count ;
break ;
2017-09-22 18:20:57 +00:00
case GSK_VULKAN_OP_CROSS_FADE :
2017-09-23 13:47:05 +00:00
op - > render . vertex_count = gsk_vulkan_cross_fade_pipeline_count_vertex_data ( GSK_VULKAN_CROSS_FADE_PIPELINE ( op - > render . pipeline ) ) ;
n_bytes + = op - > render . vertex_count ;
2017-09-22 18:20:57 +00:00
break ;
2017-09-23 05:59:50 +00:00
case GSK_VULKAN_OP_BLEND_MODE :
2017-09-23 13:47:05 +00:00
op - > render . vertex_count = gsk_vulkan_blend_mode_pipeline_count_vertex_data ( GSK_VULKAN_BLEND_MODE_PIPELINE ( op - > render . pipeline ) ) ;
n_bytes + = op - > render . vertex_count ;
2017-09-23 05:59:50 +00:00
break ;
2016-12-18 00:45:07 +00:00
default :
g_assert_not_reached ( ) ;
2017-09-28 00:56:01 +00:00
2016-12-18 00:45:07 +00:00
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS :
continue ;
}
}
2016-12-08 12:26:36 +00:00
2016-12-18 00:45:07 +00:00
return n_bytes ;
2016-12-08 12:26:36 +00:00
}
2017-09-28 00:56:01 +00:00
static gsize
2016-12-18 00:45:07 +00:00
gsk_vulkan_render_pass_collect_vertex_data ( GskVulkanRenderPass * self ,
2017-09-01 20:58:42 +00:00
GskVulkanRender * render ,
2016-12-18 00:45:07 +00:00
guchar * data ,
gsize offset ,
gsize total )
2016-12-08 12:26:36 +00:00
{
2016-12-14 06:34:18 +00:00
GskVulkanOp * op ;
2016-12-18 00:45:07 +00:00
gsize n_bytes ;
2016-12-08 12:26:36 +00:00
guint i ;
2016-12-18 00:45:07 +00:00
n_bytes = 0 ;
2016-12-08 12:26:36 +00:00
for ( i = 0 ; i < self - > render_ops - > len ; i + + )
{
2016-12-14 06:34:18 +00:00
op = & g_array_index ( self - > render_ops , GskVulkanOp , i ) ;
2016-12-08 12:26:36 +00:00
switch ( op - > type )
{
case GSK_VULKAN_OP_FALLBACK :
2016-12-23 20:36:17 +00:00
case GSK_VULKAN_OP_FALLBACK_CLIP :
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP :
2016-12-09 04:59:19 +00:00
case GSK_VULKAN_OP_TEXTURE :
2016-12-18 00:45:07 +00:00
{
op - > render . vertex_offset = offset + n_bytes ;
2017-09-30 02:24:53 +00:00
gsk_vulkan_texture_pipeline_collect_vertex_data ( GSK_VULKAN_TEXTURE_PIPELINE ( op - > render . pipeline ) ,
2017-09-30 02:41:00 +00:00
data + n_bytes + offset ,
& op - > render . node - > bounds ,
2017-10-01 23:17:39 +00:00
& op - > render . source_rect ) ;
2017-09-30 02:41:00 +00:00
n_bytes + = op - > render . vertex_count ;
}
break ;
case GSK_VULKAN_OP_REPEAT :
{
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_texture_pipeline_collect_vertex_data ( GSK_VULKAN_TEXTURE_PIPELINE ( op - > render . pipeline ) ,
data + n_bytes + offset ,
& op - > render . node - > bounds ,
2017-10-01 23:17:39 +00:00
& op - > render . source_rect ) ;
2016-12-18 00:45:07 +00:00
n_bytes + = op - > render . vertex_count ;
}
2016-12-08 12:26:36 +00:00
break ;
2017-09-01 20:58:42 +00:00
case GSK_VULKAN_OP_TEXT :
{
2017-09-19 22:53:32 +00:00
op - > text . vertex_offset = offset + n_bytes ;
gsk_vulkan_text_pipeline_collect_vertex_data ( GSK_VULKAN_TEXT_PIPELINE ( op - > text . pipeline ) ,
2017-09-01 20:58:42 +00:00
data + n_bytes + offset ,
GSK_VULKAN_RENDERER ( gsk_vulkan_render_get_renderer ( render ) ) ,
2017-09-19 22:53:32 +00:00
& op - > text . node - > bounds ,
2017-10-21 13:17:36 +00:00
( PangoFont * ) gsk_text_node_peek_font ( op - > text . node ) ,
2017-10-27 21:13:40 +00:00
gsk_text_node_get_num_glyphs ( op - > text . node ) ,
gsk_text_node_peek_glyphs ( op - > text . node ) ,
2017-10-20 07:12:19 +00:00
gsk_text_node_peek_color ( op - > text . node ) ,
2019-05-19 02:08:29 +00:00
gsk_text_node_get_offset ( op - > text . node ) ,
2017-09-19 22:53:32 +00:00
op - > text . start_glyph ,
2017-10-28 17:13:31 +00:00
op - > text . num_glyphs ,
op - > text . scale ) ;
2017-09-19 22:53:32 +00:00
n_bytes + = op - > text . vertex_count ;
2017-09-01 20:58:42 +00:00
}
break ;
case GSK_VULKAN_OP_COLOR_TEXT :
{
2017-09-19 22:53:32 +00:00
op - > text . vertex_offset = offset + n_bytes ;
gsk_vulkan_color_text_pipeline_collect_vertex_data ( GSK_VULKAN_COLOR_TEXT_PIPELINE ( op - > text . pipeline ) ,
2017-09-01 20:58:42 +00:00
data + n_bytes + offset ,
GSK_VULKAN_RENDERER ( gsk_vulkan_render_get_renderer ( render ) ) ,
2017-09-19 22:53:32 +00:00
& op - > text . node - > bounds ,
2017-10-21 13:17:36 +00:00
( PangoFont * ) gsk_text_node_peek_font ( op - > text . node ) ,
2017-10-27 21:13:40 +00:00
gsk_text_node_get_num_glyphs ( op - > text . node ) ,
gsk_text_node_peek_glyphs ( op - > text . node ) ,
2019-05-19 02:08:29 +00:00
gsk_text_node_get_offset ( op - > text . node ) ,
2017-09-19 22:53:32 +00:00
op - > text . start_glyph ,
2017-10-28 17:13:31 +00:00
op - > text . num_glyphs ,
op - > text . scale ) ;
2017-09-19 22:53:32 +00:00
n_bytes + = op - > text . vertex_count ;
2017-09-01 20:58:42 +00:00
}
break ;
2016-12-18 01:18:01 +00:00
case GSK_VULKAN_OP_COLOR :
{
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_color_pipeline_collect_vertex_data ( GSK_VULKAN_COLOR_PIPELINE ( op - > render . pipeline ) ,
data + n_bytes + offset ,
2016-12-21 17:15:50 +00:00
& op - > render . node - > bounds ,
2016-12-18 05:54:48 +00:00
gsk_color_node_peek_color ( op - > render . node ) ) ;
2016-12-18 01:18:01 +00:00
n_bytes + = op - > render . vertex_count ;
}
break ;
2016-12-26 16:11:13 +00:00
case GSK_VULKAN_OP_LINEAR_GRADIENT :
{
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_linear_gradient_pipeline_collect_vertex_data ( GSK_VULKAN_LINEAR_GRADIENT_PIPELINE ( op - > render . pipeline ) ,
data + n_bytes + offset ,
& op - > render . node - > bounds ,
gsk_linear_gradient_node_peek_start ( op - > render . node ) ,
gsk_linear_gradient_node_peek_end ( op - > render . node ) ,
gsk_render_node_get_node_type ( op - > render . node ) = = GSK_REPEATING_LINEAR_GRADIENT_NODE ,
gsk_linear_gradient_node_get_n_color_stops ( op - > render . node ) ,
gsk_linear_gradient_node_peek_color_stops ( op - > render . node ) ) ;
n_bytes + = op - > render . vertex_count ;
}
break ;
2016-12-30 05:46:34 +00:00
case GSK_VULKAN_OP_OPACITY :
{
2016-12-31 12:24:21 +00:00
graphene_matrix_t color_matrix ;
graphene_vec4_t color_offset ;
2017-10-01 23:17:39 +00:00
2016-12-31 12:24:21 +00:00
graphene_matrix_init_from_float ( & color_matrix ,
( float [ 16 ] ) {
2017-10-01 23:17:39 +00:00
1.0 , 0.0 , 0.0 , 0.0 ,
0.0 , 1.0 , 0.0 , 0.0 ,
0.0 , 0.0 , 1.0 , 0.0 ,
2016-12-31 12:24:21 +00:00
0.0 , 0.0 , 0.0 , gsk_opacity_node_get_opacity ( op - > render . node )
} ) ;
graphene_vec4_init ( & color_offset , 0.0 , 0.0 , 0.0 , 0.0 ) ;
2016-12-30 05:46:34 +00:00
op - > render . vertex_offset = offset + n_bytes ;
2017-10-01 23:17:39 +00:00
2016-12-30 05:46:34 +00:00
gsk_vulkan_effect_pipeline_collect_vertex_data ( GSK_VULKAN_EFFECT_PIPELINE ( op - > render . pipeline ) ,
data + n_bytes + offset ,
& op - > render . node - > bounds ,
2017-10-01 23:17:39 +00:00
& op - > render . source_rect ,
2016-12-31 12:24:21 +00:00
& color_matrix ,
& color_offset ) ;
2016-12-30 05:46:34 +00:00
n_bytes + = op - > render . vertex_count ;
}
break ;
2017-09-03 13:54:47 +00:00
case GSK_VULKAN_OP_BLUR :
{
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_blur_pipeline_collect_vertex_data ( GSK_VULKAN_BLUR_PIPELINE ( op - > render . pipeline ) ,
data + n_bytes + offset ,
& op - > render . node - > bounds ,
2017-10-01 23:17:39 +00:00
& op - > render . source_rect ,
2017-09-03 13:54:47 +00:00
gsk_blur_node_get_radius ( op - > render . node ) ) ;
n_bytes + = op - > render . vertex_count ;
}
break ;
2016-12-31 13:14:26 +00:00
case GSK_VULKAN_OP_COLOR_MATRIX :
{
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_effect_pipeline_collect_vertex_data ( GSK_VULKAN_EFFECT_PIPELINE ( op - > render . pipeline ) ,
data + n_bytes + offset ,
& op - > render . node - > bounds ,
2017-10-01 23:17:39 +00:00
& op - > render . source_rect ,
2016-12-31 13:14:26 +00:00
gsk_color_matrix_node_peek_color_matrix ( op - > render . node ) ,
gsk_color_matrix_node_peek_color_offset ( op - > render . node ) ) ;
n_bytes + = op - > render . vertex_count ;
}
break ;
2016-12-30 05:46:34 +00:00
2017-01-10 13:59:20 +00:00
case GSK_VULKAN_OP_BORDER :
{
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_border_pipeline_collect_vertex_data ( GSK_VULKAN_BORDER_PIPELINE ( op - > render . pipeline ) ,
data + n_bytes + offset ,
gsk_border_node_peek_outline ( op - > render . node ) ,
gsk_border_node_peek_widths ( op - > render . node ) ,
gsk_border_node_peek_colors ( op - > render . node ) ) ;
n_bytes + = op - > render . vertex_count ;
}
break ;
2017-01-18 03:07:09 +00:00
case GSK_VULKAN_OP_INSET_SHADOW :
{
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_box_shadow_pipeline_collect_vertex_data ( GSK_VULKAN_BOX_SHADOW_PIPELINE ( op - > render . pipeline ) ,
data + n_bytes + offset ,
gsk_inset_shadow_node_peek_outline ( op - > render . node ) ,
gsk_inset_shadow_node_peek_color ( op - > render . node ) ,
gsk_inset_shadow_node_get_dx ( op - > render . node ) ,
gsk_inset_shadow_node_get_dy ( op - > render . node ) ,
gsk_inset_shadow_node_get_spread ( op - > render . node ) ,
gsk_inset_shadow_node_get_blur_radius ( op - > render . node ) ) ;
n_bytes + = op - > render . vertex_count ;
}
break ;
case GSK_VULKAN_OP_OUTSET_SHADOW :
{
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_box_shadow_pipeline_collect_vertex_data ( GSK_VULKAN_BOX_SHADOW_PIPELINE ( op - > render . pipeline ) ,
data + n_bytes + offset ,
gsk_outset_shadow_node_peek_outline ( op - > render . node ) ,
gsk_outset_shadow_node_peek_color ( op - > render . node ) ,
gsk_outset_shadow_node_get_dx ( op - > render . node ) ,
gsk_outset_shadow_node_get_dy ( op - > render . node ) ,
gsk_outset_shadow_node_get_spread ( op - > render . node ) ,
gsk_outset_shadow_node_get_blur_radius ( op - > render . node ) ) ;
n_bytes + = op - > render . vertex_count ;
}
break ;
2017-09-22 18:20:57 +00:00
case GSK_VULKAN_OP_CROSS_FADE :
{
2017-09-23 13:47:05 +00:00
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_cross_fade_pipeline_collect_vertex_data ( GSK_VULKAN_CROSS_FADE_PIPELINE ( op - > render . pipeline ) ,
2017-09-22 18:20:57 +00:00
data + n_bytes + offset ,
2017-09-23 13:47:05 +00:00
& op - > render . node - > bounds ,
2017-10-01 23:17:39 +00:00
& op - > render . source_rect ,
& op - > render . source2_rect ,
2017-09-23 13:47:05 +00:00
gsk_cross_fade_node_get_progress ( op - > render . node ) ) ;
n_bytes + = op - > render . vertex_count ;
2017-09-22 18:20:57 +00:00
}
break ;
2017-09-23 05:59:50 +00:00
case GSK_VULKAN_OP_BLEND_MODE :
{
2017-09-23 13:47:05 +00:00
op - > render . vertex_offset = offset + n_bytes ;
gsk_vulkan_blend_mode_pipeline_collect_vertex_data ( GSK_VULKAN_BLEND_MODE_PIPELINE ( op - > render . pipeline ) ,
2017-09-23 05:59:50 +00:00
data + n_bytes + offset ,
2017-09-23 13:47:05 +00:00
& op - > render . node - > bounds ,
2017-10-01 23:17:39 +00:00
& op - > render . source_rect ,
& op - > render . source2_rect ,
2017-09-23 13:47:05 +00:00
gsk_blend_node_get_blend_mode ( op - > render . node ) ) ;
n_bytes + = op - > render . vertex_count ;
2017-09-23 05:59:50 +00:00
}
break ;
2016-12-08 12:26:36 +00:00
default :
g_assert_not_reached ( ) ;
2016-12-14 06:21:21 +00:00
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS :
2016-12-14 06:34:18 +00:00
continue ;
2016-12-08 12:26:36 +00:00
}
2016-12-18 00:45:07 +00:00
g_assert ( n_bytes + offset < = total ) ;
2016-12-08 12:26:36 +00:00
}
2016-12-18 00:45:07 +00:00
return n_bytes ;
2016-12-08 12:26:36 +00:00
}
2017-09-28 00:56:01 +00:00
static GskVulkanBuffer *
2017-09-28 00:55:14 +00:00
gsk_vulkan_render_pass_get_vertex_data ( GskVulkanRenderPass * self ,
GskVulkanRender * render )
{
2017-09-28 00:56:01 +00:00
if ( self - > vertex_data = = NULL )
{
gsize n_bytes ;
guchar * data ;
n_bytes = gsk_vulkan_render_pass_count_vertex_data ( self ) ;
self - > vertex_data = gsk_vulkan_buffer_new ( self - > vulkan , n_bytes ) ;
data = gsk_vulkan_buffer_map ( self - > vertex_data ) ;
gsk_vulkan_render_pass_collect_vertex_data ( self , render , data , 0 , n_bytes ) ;
gsk_vulkan_buffer_unmap ( self - > vertex_data ) ;
}
2017-09-28 00:55:14 +00:00
2017-09-28 00:56:01 +00:00
return self - > vertex_data ;
}
2017-09-28 00:55:14 +00:00
2017-09-28 00:56:01 +00:00
gsize
gsk_vulkan_render_pass_get_wait_semaphores ( GskVulkanRenderPass * self ,
VkSemaphore * * semaphores )
{
* semaphores = ( VkSemaphore * ) self - > wait_semaphores - > data ;
return self - > wait_semaphores - > len ;
}
2017-09-28 00:55:14 +00:00
2017-09-28 00:56:01 +00:00
gsize
gsk_vulkan_render_pass_get_signal_semaphores ( GskVulkanRenderPass * self ,
VkSemaphore * * semaphores )
{
* semaphores = ( VkSemaphore * ) & self - > signal_semaphore ;
return self - > signal_semaphore ! = VK_NULL_HANDLE ? 1 : 0 ;
2017-09-28 00:55:14 +00:00
}
2016-12-08 12:26:36 +00:00
void
2016-12-09 01:55:47 +00:00
gsk_vulkan_render_pass_reserve_descriptor_sets ( GskVulkanRenderPass * self ,
GskVulkanRender * render )
2016-12-08 12:26:36 +00:00
{
2016-12-14 06:34:18 +00:00
GskVulkanOp * op ;
2016-12-08 12:26:36 +00:00
guint i ;
for ( i = 0 ; i < self - > render_ops - > len ; i + + )
{
2016-12-14 06:34:18 +00:00
op = & g_array_index ( self - > render_ops , GskVulkanOp , i ) ;
2016-12-08 12:26:36 +00:00
2016-12-09 01:55:47 +00:00
switch ( op - > type )
{
case GSK_VULKAN_OP_FALLBACK :
2016-12-23 20:36:17 +00:00
case GSK_VULKAN_OP_FALLBACK_CLIP :
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP :
2016-12-09 04:59:19 +00:00
case GSK_VULKAN_OP_TEXTURE :
2016-12-30 05:46:34 +00:00
case GSK_VULKAN_OP_OPACITY :
2017-09-03 13:54:47 +00:00
case GSK_VULKAN_OP_BLUR :
2016-12-31 13:14:26 +00:00
case GSK_VULKAN_OP_COLOR_MATRIX :
2017-10-01 23:17:39 +00:00
if ( op - > render . source )
op - > render . descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set ( render , op - > render . source , FALSE ) ;
2016-12-09 01:55:47 +00:00
break ;
2017-09-30 02:41:00 +00:00
case GSK_VULKAN_OP_REPEAT :
2017-10-01 23:17:39 +00:00
if ( op - > render . source )
op - > render . descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set ( render , op - > render . source , TRUE ) ;
2017-09-30 02:41:00 +00:00
break ;
2017-09-19 22:53:32 +00:00
case GSK_VULKAN_OP_TEXT :
case GSK_VULKAN_OP_COLOR_TEXT :
2017-09-30 03:01:34 +00:00
op - > text . descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set ( render , op - > text . source , FALSE ) ;
2017-09-19 22:53:32 +00:00
break ;
2017-09-22 18:20:57 +00:00
case GSK_VULKAN_OP_CROSS_FADE :
2017-09-23 05:59:50 +00:00
case GSK_VULKAN_OP_BLEND_MODE :
2017-10-01 23:17:39 +00:00
if ( op - > render . source & & op - > render . source2 )
{
op - > render . descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set ( render , op - > render . source , FALSE ) ;
op - > render . descriptor_set_index2 = gsk_vulkan_render_reserve_descriptor_set ( render , op - > render . source2 , FALSE ) ;
}
2017-09-22 18:20:57 +00:00
break ;
2016-12-09 01:55:47 +00:00
default :
g_assert_not_reached ( ) ;
2017-09-28 00:56:01 +00:00
2016-12-14 08:40:15 +00:00
case GSK_VULKAN_OP_COLOR :
2016-12-26 16:11:13 +00:00
case GSK_VULKAN_OP_LINEAR_GRADIENT :
2016-12-14 06:21:21 +00:00
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS :
2017-01-10 13:59:20 +00:00
case GSK_VULKAN_OP_BORDER :
2017-01-18 03:07:09 +00:00
case GSK_VULKAN_OP_INSET_SHADOW :
case GSK_VULKAN_OP_OUTSET_SHADOW :
2016-12-09 01:55:47 +00:00
break ;
}
2016-12-08 12:26:36 +00:00
}
}
2017-09-28 00:56:01 +00:00
static void
gsk_vulkan_render_pass_draw_rect ( GskVulkanRenderPass * self ,
GskVulkanRender * render ,
guint layout_count ,
VkPipelineLayout * pipeline_layout ,
VkCommandBuffer command_buffer )
2016-12-08 12:26:36 +00:00
{
2016-12-14 08:40:15 +00:00
GskVulkanPipeline * current_pipeline = NULL ;
2016-12-18 00:45:07 +00:00
gsize current_draw_index = 0 ;
2016-12-14 06:34:18 +00:00
GskVulkanOp * op ;
2016-12-23 21:19:56 +00:00
guint i , step ;
2017-09-28 00:56:01 +00:00
GskVulkanBuffer * vertex_buffer ;
vertex_buffer = gsk_vulkan_render_pass_get_vertex_data ( self , render ) ;
2016-12-08 12:26:36 +00:00
2016-12-23 21:19:56 +00:00
for ( i = 0 ; i < self - > render_ops - > len ; i + = step )
2016-12-08 12:26:36 +00:00
{
2016-12-14 06:34:18 +00:00
op = & g_array_index ( self - > render_ops , GskVulkanOp , i ) ;
2016-12-23 21:19:56 +00:00
step = 1 ;
2016-12-08 12:26:36 +00:00
2016-12-12 23:11:06 +00:00
switch ( op - > type )
{
case GSK_VULKAN_OP_FALLBACK :
2016-12-23 20:36:17 +00:00
case GSK_VULKAN_OP_FALLBACK_CLIP :
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP :
2016-12-12 23:11:06 +00:00
case GSK_VULKAN_OP_TEXTURE :
2017-09-30 02:41:00 +00:00
case GSK_VULKAN_OP_REPEAT :
2017-10-01 23:17:39 +00:00
if ( ! op - > render . source )
continue ;
2016-12-18 01:18:01 +00:00
if ( current_pipeline ! = op - > render . pipeline )
{
current_pipeline = op - > render . pipeline ;
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
( VkDeviceSize [ 1 ] ) { op - > render . vertex_offset } ) ;
current_draw_index = 0 ;
}
2016-12-12 23:11:06 +00:00
vkCmdBindDescriptorSets ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
2017-09-22 14:35:19 +00:00
gsk_vulkan_pipeline_get_pipeline_layout ( current_pipeline ) ,
2016-12-12 23:11:06 +00:00
0 ,
1 ,
( VkDescriptorSet [ 1 ] ) {
2016-12-14 06:34:18 +00:00
gsk_vulkan_render_get_descriptor_set ( render , op - > render . descriptor_set_index )
2016-12-12 23:11:06 +00:00
} ,
0 ,
NULL ) ;
2016-12-18 01:18:01 +00:00
2017-09-30 02:24:53 +00:00
current_draw_index + = gsk_vulkan_texture_pipeline_draw ( GSK_VULKAN_TEXTURE_PIPELINE ( current_pipeline ) ,
command_buffer ,
current_draw_index , 1 ) ;
2016-12-30 05:46:34 +00:00
break ;
2017-09-01 20:58:42 +00:00
case GSK_VULKAN_OP_TEXT :
2017-09-19 22:53:32 +00:00
if ( current_pipeline ! = op - > text . pipeline )
2017-09-01 20:58:42 +00:00
{
2017-09-19 22:53:32 +00:00
current_pipeline = op - > text . pipeline ;
2017-09-01 20:58:42 +00:00
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
2017-09-19 22:53:32 +00:00
( VkDeviceSize [ 1 ] ) { op - > text . vertex_offset } ) ;
2017-09-01 20:58:42 +00:00
current_draw_index = 0 ;
}
vkCmdBindDescriptorSets ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
2017-09-22 14:35:19 +00:00
gsk_vulkan_pipeline_get_pipeline_layout ( current_pipeline ) ,
2017-09-01 20:58:42 +00:00
0 ,
1 ,
( VkDescriptorSet [ 1 ] ) {
2017-09-19 22:53:32 +00:00
gsk_vulkan_render_get_descriptor_set ( render , op - > text . descriptor_set_index )
2017-09-01 20:58:42 +00:00
} ,
0 ,
NULL ) ;
current_draw_index + = gsk_vulkan_text_pipeline_draw ( GSK_VULKAN_TEXT_PIPELINE ( current_pipeline ) ,
2017-09-19 22:53:32 +00:00
command_buffer ,
current_draw_index , op - > text . num_glyphs ) ;
2017-09-01 20:58:42 +00:00
break ;
case GSK_VULKAN_OP_COLOR_TEXT :
2017-09-19 22:53:32 +00:00
if ( current_pipeline ! = op - > text . pipeline )
2017-09-01 20:58:42 +00:00
{
2017-09-19 22:53:32 +00:00
current_pipeline = op - > text . pipeline ;
2017-09-01 20:58:42 +00:00
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
2017-09-19 22:53:32 +00:00
( VkDeviceSize [ 1 ] ) { op - > text . vertex_offset } ) ;
2017-09-01 20:58:42 +00:00
current_draw_index = 0 ;
}
vkCmdBindDescriptorSets ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
2017-09-22 14:35:19 +00:00
gsk_vulkan_pipeline_get_pipeline_layout ( current_pipeline ) ,
2017-09-01 20:58:42 +00:00
0 ,
1 ,
( VkDescriptorSet [ 1 ] ) {
2017-09-19 22:53:32 +00:00
gsk_vulkan_render_get_descriptor_set ( render , op - > text . descriptor_set_index )
2017-09-01 20:58:42 +00:00
} ,
0 ,
NULL ) ;
current_draw_index + = gsk_vulkan_color_text_pipeline_draw ( GSK_VULKAN_COLOR_TEXT_PIPELINE ( current_pipeline ) ,
command_buffer ,
2017-09-19 22:53:32 +00:00
current_draw_index , op - > text . num_glyphs ) ;
2017-09-01 20:58:42 +00:00
break ;
2016-12-30 05:46:34 +00:00
case GSK_VULKAN_OP_OPACITY :
2016-12-31 13:14:26 +00:00
case GSK_VULKAN_OP_COLOR_MATRIX :
2017-10-01 23:17:39 +00:00
if ( ! op - > render . source )
continue ;
2016-12-30 05:46:34 +00:00
if ( current_pipeline ! = op - > render . pipeline )
{
current_pipeline = op - > render . pipeline ;
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
( VkDeviceSize [ 1 ] ) { op - > render . vertex_offset } ) ;
current_draw_index = 0 ;
}
vkCmdBindDescriptorSets ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
2017-09-22 14:35:19 +00:00
gsk_vulkan_pipeline_get_pipeline_layout ( current_pipeline ) ,
2016-12-30 05:46:34 +00:00
0 ,
1 ,
( VkDescriptorSet [ 1 ] ) {
gsk_vulkan_render_get_descriptor_set ( render , op - > render . descriptor_set_index )
} ,
0 ,
NULL ) ;
current_draw_index + = gsk_vulkan_effect_pipeline_draw ( GSK_VULKAN_EFFECT_PIPELINE ( current_pipeline ) ,
command_buffer ,
current_draw_index , 1 ) ;
2016-12-18 01:18:01 +00:00
break ;
2017-09-03 13:54:47 +00:00
case GSK_VULKAN_OP_BLUR :
2017-10-01 23:17:39 +00:00
if ( ! op - > render . source )
continue ;
2017-09-03 13:54:47 +00:00
if ( current_pipeline ! = op - > render . pipeline )
{
current_pipeline = op - > render . pipeline ;
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
( VkDeviceSize [ 1 ] ) { op - > render . vertex_offset } ) ;
current_draw_index = 0 ;
}
vkCmdBindDescriptorSets ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
2017-09-22 14:35:19 +00:00
gsk_vulkan_pipeline_get_pipeline_layout ( current_pipeline ) ,
2017-09-03 13:54:47 +00:00
0 ,
1 ,
( VkDescriptorSet [ 1 ] ) {
gsk_vulkan_render_get_descriptor_set ( render , op - > render . descriptor_set_index )
} ,
0 ,
NULL ) ;
current_draw_index + = gsk_vulkan_blur_pipeline_draw ( GSK_VULKAN_BLUR_PIPELINE ( current_pipeline ) ,
command_buffer ,
current_draw_index , 1 ) ;
break ;
2016-12-14 08:40:15 +00:00
case GSK_VULKAN_OP_COLOR :
if ( current_pipeline ! = op - > render . pipeline )
{
current_pipeline = op - > render . pipeline ;
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
2016-12-18 00:45:07 +00:00
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
( VkDeviceSize [ 1 ] ) { op - > render . vertex_offset } ) ;
current_draw_index = 0 ;
2016-12-14 08:40:15 +00:00
}
2016-12-12 23:11:06 +00:00
2016-12-23 21:19:56 +00:00
for ( step = 1 ; step + i < self - > render_ops - > len ; step + + )
{
2016-12-25 05:01:54 +00:00
GskVulkanOp * cmp = & g_array_index ( self - > render_ops , GskVulkanOp , i + step ) ;
if ( cmp - > type ! = GSK_VULKAN_OP_COLOR | |
cmp - > render . pipeline ! = current_pipeline )
2016-12-23 21:19:56 +00:00
break ;
}
2016-12-18 01:18:01 +00:00
current_draw_index + = gsk_vulkan_color_pipeline_draw ( GSK_VULKAN_COLOR_PIPELINE ( current_pipeline ) ,
2016-12-18 00:45:07 +00:00
command_buffer ,
2016-12-23 21:19:56 +00:00
current_draw_index , step ) ;
2016-12-12 23:11:06 +00:00
break ;
2016-12-26 16:11:13 +00:00
case GSK_VULKAN_OP_LINEAR_GRADIENT :
if ( current_pipeline ! = op - > render . pipeline )
{
current_pipeline = op - > render . pipeline ;
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
( VkDeviceSize [ 1 ] ) { op - > render . vertex_offset } ) ;
current_draw_index = 0 ;
}
current_draw_index + = gsk_vulkan_linear_gradient_pipeline_draw ( GSK_VULKAN_LINEAR_GRADIENT_PIPELINE ( current_pipeline ) ,
command_buffer ,
current_draw_index , 1 ) ;
break ;
2017-01-10 13:59:20 +00:00
case GSK_VULKAN_OP_BORDER :
if ( current_pipeline ! = op - > render . pipeline )
{
current_pipeline = op - > render . pipeline ;
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
( VkDeviceSize [ 1 ] ) { op - > render . vertex_offset } ) ;
current_draw_index = 0 ;
}
current_draw_index + = gsk_vulkan_border_pipeline_draw ( GSK_VULKAN_BORDER_PIPELINE ( current_pipeline ) ,
command_buffer ,
current_draw_index , 1 ) ;
break ;
2017-01-18 03:07:09 +00:00
case GSK_VULKAN_OP_INSET_SHADOW :
case GSK_VULKAN_OP_OUTSET_SHADOW :
if ( current_pipeline ! = op - > render . pipeline )
{
current_pipeline = op - > render . pipeline ;
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
( VkDeviceSize [ 1 ] ) { op - > render . vertex_offset } ) ;
current_draw_index = 0 ;
}
current_draw_index + = gsk_vulkan_box_shadow_pipeline_draw ( GSK_VULKAN_BOX_SHADOW_PIPELINE ( current_pipeline ) ,
command_buffer ,
current_draw_index , 1 ) ;
break ;
2016-12-14 06:21:21 +00:00
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS :
2019-01-22 03:30:47 +00:00
for ( int j = 0 ; j < layout_count ; j + + )
2017-09-22 14:35:19 +00:00
gsk_vulkan_push_constants_push ( & op - > constants . constants ,
2017-09-22 17:30:26 +00:00
command_buffer ,
2019-01-22 03:30:47 +00:00
pipeline_layout [ j ] ) ;
2016-12-14 06:21:21 +00:00
break ;
2016-12-12 23:11:06 +00:00
2017-09-22 18:20:57 +00:00
case GSK_VULKAN_OP_CROSS_FADE :
2017-10-01 23:17:39 +00:00
if ( ! op - > render . source | | ! op - > render . source2 )
continue ;
2017-09-23 13:47:05 +00:00
if ( current_pipeline ! = op - > render . pipeline )
2017-09-22 18:20:57 +00:00
{
2017-09-23 13:47:05 +00:00
current_pipeline = op - > render . pipeline ;
2017-09-22 18:20:57 +00:00
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
2017-09-23 13:47:05 +00:00
( VkDeviceSize [ 1 ] ) { op - > render . vertex_offset } ) ;
2017-09-22 18:20:57 +00:00
current_draw_index = 0 ;
}
vkCmdBindDescriptorSets ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline_layout ( current_pipeline ) ,
0 ,
2 ,
( VkDescriptorSet [ 2 ] ) {
2017-09-23 13:47:05 +00:00
gsk_vulkan_render_get_descriptor_set ( render , op - > render . descriptor_set_index ) ,
gsk_vulkan_render_get_descriptor_set ( render , op - > render . descriptor_set_index2 )
2017-09-22 18:20:57 +00:00
} ,
0 ,
NULL ) ;
current_draw_index + = gsk_vulkan_cross_fade_pipeline_draw ( GSK_VULKAN_CROSS_FADE_PIPELINE ( current_pipeline ) ,
command_buffer ,
current_draw_index , 1 ) ;
break ;
2017-09-23 05:59:50 +00:00
case GSK_VULKAN_OP_BLEND_MODE :
2017-10-01 23:17:39 +00:00
if ( ! op - > render . source | | ! op - > render . source2 )
continue ;
2017-09-23 13:47:05 +00:00
if ( current_pipeline ! = op - > render . pipeline )
2017-09-23 05:59:50 +00:00
{
2017-09-23 13:47:05 +00:00
current_pipeline = op - > render . pipeline ;
2017-09-23 05:59:50 +00:00
vkCmdBindPipeline ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline ( current_pipeline ) ) ;
vkCmdBindVertexBuffers ( command_buffer ,
0 ,
1 ,
( VkBuffer [ 1 ] ) {
gsk_vulkan_buffer_get_buffer ( vertex_buffer )
} ,
2017-09-23 13:47:05 +00:00
( VkDeviceSize [ 1 ] ) { op - > render . vertex_offset } ) ;
2017-09-23 05:59:50 +00:00
current_draw_index = 0 ;
}
vkCmdBindDescriptorSets ( command_buffer ,
VK_PIPELINE_BIND_POINT_GRAPHICS ,
gsk_vulkan_pipeline_get_pipeline_layout ( current_pipeline ) ,
0 ,
2 ,
( VkDescriptorSet [ 2 ] ) {
2017-09-23 13:47:05 +00:00
gsk_vulkan_render_get_descriptor_set ( render , op - > render . descriptor_set_index ) ,
gsk_vulkan_render_get_descriptor_set ( render , op - > render . descriptor_set_index2 )
2017-09-23 05:59:50 +00:00
} ,
0 ,
NULL ) ;
current_draw_index + = gsk_vulkan_blend_mode_pipeline_draw ( GSK_VULKAN_BLEND_MODE_PIPELINE ( current_pipeline ) ,
command_buffer ,
current_draw_index , 1 ) ;
break ;
2016-12-12 23:11:06 +00:00
default :
g_assert_not_reached ( ) ;
break ;
}
2016-12-08 12:26:36 +00:00
}
}
2017-09-28 00:56:01 +00:00
void
gsk_vulkan_render_pass_draw ( GskVulkanRenderPass * self ,
GskVulkanRender * render ,
guint layout_count ,
VkPipelineLayout * pipeline_layout ,
VkCommandBuffer command_buffer )
{
guint i ;
vkCmdSetViewport ( command_buffer ,
0 ,
1 ,
& ( VkViewport ) {
. x = 0 ,
. y = 0 ,
. width = self - > viewport . size . width ,
. height = self - > viewport . size . height ,
. minDepth = 0 ,
. maxDepth = 1
} ) ;
for ( i = 0 ; i < cairo_region_num_rectangles ( self - > clip ) ; i + + )
{
cairo_rectangle_int_t rect ;
cairo_region_get_rectangle ( self - > clip , i , & rect ) ;
vkCmdSetScissor ( command_buffer ,
0 ,
1 ,
& ( VkRect2D ) {
{ rect . x * self - > scale_factor , rect . y * self - > scale_factor } ,
{ rect . width * self - > scale_factor , rect . height * self - > scale_factor }
} ) ;
vkCmdBeginRenderPass ( command_buffer ,
& ( VkRenderPassBeginInfo ) {
. sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO ,
. renderPass = self - > render_pass ,
. framebuffer = gsk_vulkan_render_get_framebuffer ( render , self - > target ) ,
. renderArea = {
{ rect . x * self - > scale_factor , rect . y * self - > scale_factor } ,
{ rect . width * self - > scale_factor , rect . height * self - > scale_factor }
} ,
. clearValueCount = 1 ,
. pClearValues = ( VkClearValue [ 1 ] ) {
{ . color = { . float32 = { 0.f , 0.f , 0.f , 0.f } } }
}
} ,
VK_SUBPASS_CONTENTS_INLINE ) ;
gsk_vulkan_render_pass_draw_rect ( self , render , layout_count , pipeline_layout , command_buffer ) ;
vkCmdEndRenderPass ( command_buffer ) ;
}
}