diff options
Diffstat (limited to 'gsk')
-rw-r--r-- | gsk/gskvulkanblendmodepipeline.c | 20 | ||||
-rw-r--r-- | gsk/gskvulkanblurpipeline.c | 9 | ||||
-rw-r--r-- | gsk/gskvulkanblurpipelineprivate.h | 1 | ||||
-rw-r--r-- | gsk/gskvulkancrossfadepipeline.c | 20 | ||||
-rw-r--r-- | gsk/gskvulkaneffectpipeline.c | 9 | ||||
-rw-r--r-- | gsk/gskvulkaneffectpipelineprivate.h | 1 | ||||
-rw-r--r-- | gsk/gskvulkanrenderpass.c | 252 | ||||
-rw-r--r-- | gsk/gskvulkantexturepipeline.c | 8 |
8 files changed, 197 insertions, 123 deletions
diff --git a/gsk/gskvulkanblendmodepipeline.c b/gsk/gskvulkanblendmodepipeline.c index 062921e0b2..117ed414d5 100644 --- a/gsk/gskvulkanblendmodepipeline.c +++ b/gsk/gskvulkanblendmodepipeline.c @@ -108,8 +108,8 @@ void gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GskVulkanBlendModePipeline *pipeline, guchar *data, const graphene_rect_t *bounds, - const graphene_rect_t *start_bounds, - const graphene_rect_t *end_bounds, + const graphene_rect_t *start_tex_rect, + const graphene_rect_t *end_tex_rect, GskBlendMode blend_mode) { GskVulkanBlendModeInstance *instance = (GskVulkanBlendModeInstance *) data; @@ -119,15 +119,15 @@ gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GskVulkanBlendModePipeline * instance->rect[2] = bounds->size.width; instance->rect[3] = bounds->size.height; - instance->start_tex_rect[0] = (bounds->origin.x - start_bounds->origin.x)/start_bounds->size.width; - instance->start_tex_rect[1] = (bounds->origin.y - start_bounds->origin.y)/start_bounds->size.height; - instance->start_tex_rect[2] = (bounds->size.width + bounds->origin.x - start_bounds->origin.x)/start_bounds->size.width; - instance->start_tex_rect[3] = (bounds->size.height + bounds->origin.y - start_bounds->origin.y)/start_bounds->size.height; + instance->start_tex_rect[0] = start_tex_rect->origin.x; + instance->start_tex_rect[1] = start_tex_rect->origin.y; + instance->start_tex_rect[2] = start_tex_rect->size.width; + instance->start_tex_rect[3] = start_tex_rect->size.height; - instance->end_tex_rect[0] = (bounds->origin.x - end_bounds->origin.x)/end_bounds->size.width; - instance->end_tex_rect[1] = (bounds->origin.y - end_bounds->origin.y)/end_bounds->size.height; - instance->end_tex_rect[2] = (bounds->size.width + bounds->origin.x - end_bounds->origin.x)/end_bounds->size.width; - instance->end_tex_rect[3] = (bounds->size.height + bounds->origin.y - end_bounds->origin.y)/end_bounds->size.height; + instance->end_tex_rect[0] = end_tex_rect->origin.x; + instance->end_tex_rect[1] = end_tex_rect->origin.y; + instance->end_tex_rect[2] = end_tex_rect->size.width; + instance->end_tex_rect[3] = end_tex_rect->size.height; instance->blend_mode = blend_mode; } diff --git a/gsk/gskvulkanblurpipeline.c b/gsk/gskvulkanblurpipeline.c index 6e9bff19a3..5686e5423a 100644 --- a/gsk/gskvulkanblurpipeline.c +++ b/gsk/gskvulkanblurpipeline.c @@ -101,6 +101,7 @@ void gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline, guchar *data, const graphene_rect_t *rect, + const graphene_rect_t *tex_rect, double blur_radius) { GskVulkanBlurInstance *instance = (GskVulkanBlurInstance *) data; @@ -109,10 +110,10 @@ gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline, instance->rect[1] = rect->origin.y; instance->rect[2] = rect->size.width; instance->rect[3] = rect->size.height; - instance->tex_rect[0] = 0.0; - instance->tex_rect[1] = 0.0; - instance->tex_rect[2] = 1.0; - instance->tex_rect[3] = 1.0; + instance->tex_rect[0] = tex_rect->origin.x; + instance->tex_rect[1] = tex_rect->origin.y; + instance->tex_rect[2] = tex_rect->size.width; + instance->tex_rect[3] = tex_rect->size.height; instance->blur_radius = blur_radius; } diff --git a/gsk/gskvulkanblurpipelineprivate.h b/gsk/gskvulkanblurpipelineprivate.h index 2fc4273668..0fc2cb6705 100644 --- a/gsk/gskvulkanblurpipelineprivate.h +++ b/gsk/gskvulkanblurpipelineprivate.h @@ -22,6 +22,7 @@ gsize gsk_vulkan_blur_pipeline_count_vertex_data (GskVulka void gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline, guchar *data, const graphene_rect_t *rect, + const graphene_rect_t *tex_rect, double radius); gsize gsk_vulkan_blur_pipeline_draw (GskVulkanBlurPipeline *pipeline, VkCommandBuffer command_buffer, diff --git a/gsk/gskvulkancrossfadepipeline.c b/gsk/gskvulkancrossfadepipeline.c index a0de8c3d56..679c583c6e 100644 --- a/gsk/gskvulkancrossfadepipeline.c +++ b/gsk/gskvulkancrossfadepipeline.c @@ -108,8 +108,8 @@ void gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GskVulkanCrossFadePipeline *pipeline, guchar *data, const graphene_rect_t *bounds, - const graphene_rect_t *start_bounds, - const graphene_rect_t *end_bounds, + const graphene_rect_t *start_tex_rect, + const graphene_rect_t *end_tex_rect, double progress) { GskVulkanCrossFadeInstance *instance = (GskVulkanCrossFadeInstance *) data; @@ -119,15 +119,15 @@ gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GskVulkanCrossFadePipeline * instance->rect[2] = bounds->size.width; instance->rect[3] = bounds->size.height; - instance->start_tex_rect[0] = (bounds->origin.x - start_bounds->origin.x)/start_bounds->size.width; - instance->start_tex_rect[1] = (bounds->origin.y - start_bounds->origin.y)/start_bounds->size.height; - instance->start_tex_rect[2] = (bounds->size.width + bounds->origin.x - start_bounds->origin.x)/start_bounds->size.width; - instance->start_tex_rect[3] = (bounds->size.height + bounds->origin.y - start_bounds->origin.y)/start_bounds->size.height; + instance->start_tex_rect[0] = start_tex_rect->origin.x; + instance->start_tex_rect[1] = start_tex_rect->origin.y; + instance->start_tex_rect[2] = start_tex_rect->size.width; + instance->start_tex_rect[3] = start_tex_rect->size.height; - instance->end_tex_rect[0] = (bounds->origin.x - end_bounds->origin.x)/end_bounds->size.width; - instance->end_tex_rect[1] = (bounds->origin.y - end_bounds->origin.y)/end_bounds->size.height; - instance->end_tex_rect[2] = (bounds->size.width + bounds->origin.x - end_bounds->origin.x)/end_bounds->size.width; - instance->end_tex_rect[3] = (bounds->size.height + bounds->origin.y - end_bounds->origin.y)/end_bounds->size.height; + instance->end_tex_rect[0] = end_tex_rect->origin.x; + instance->end_tex_rect[1] = end_tex_rect->origin.y; + instance->end_tex_rect[2] = end_tex_rect->size.width; + instance->end_tex_rect[3] = end_tex_rect->size.height; instance->progress = progress; } diff --git a/gsk/gskvulkaneffectpipeline.c b/gsk/gskvulkaneffectpipeline.c index 1db9ec6350..aa9973c711 100644 --- a/gsk/gskvulkaneffectpipeline.c +++ b/gsk/gskvulkaneffectpipeline.c @@ -126,6 +126,7 @@ void gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipeline, guchar *data, const graphene_rect_t *rect, + const graphene_rect_t *tex_rect, const graphene_matrix_t *color_matrix, const graphene_vec4_t *color_offset) { @@ -135,10 +136,10 @@ gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipelin instance->rect[1] = rect->origin.y; instance->rect[2] = rect->size.width; instance->rect[3] = rect->size.height; - instance->tex_rect[0] = 0.0; - instance->tex_rect[1] = 0.0; - instance->tex_rect[2] = 1.0; - instance->tex_rect[3] = 1.0; + instance->tex_rect[0] = tex_rect->origin.x; + instance->tex_rect[1] = tex_rect->origin.y; + instance->tex_rect[2] = tex_rect->size.width; + instance->tex_rect[3] = tex_rect->size.height; graphene_matrix_to_float (color_matrix, instance->color_matrix); graphene_vec4_to_float (color_offset, instance->color_offset); } diff --git a/gsk/gskvulkaneffectpipelineprivate.h b/gsk/gskvulkaneffectpipelineprivate.h index 8e3b976bdb..45ac6af9c8 100644 --- a/gsk/gskvulkaneffectpipelineprivate.h +++ b/gsk/gskvulkaneffectpipelineprivate.h @@ -22,6 +22,7 @@ gsize gsk_vulkan_effect_pipeline_count_vertex_data (GskVulk void gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipeline, guchar *data, const graphene_rect_t *rect, + const graphene_rect_t *tex_rect, const graphene_matrix_t *color_matrix, const graphene_vec4_t *color_offset); gsize gsk_vulkan_effect_pipeline_draw (GskVulkanEffectPipeline *pipeline, diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index 6b10345f53..770ebdb5e4 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -73,6 +73,8 @@ struct _GskVulkanOpRender gsize vertex_count; /* number of vertices */ gsize descriptor_set_index; /* index into descriptor sets array for the right descriptor set to bind */ gsize descriptor_set_index2; /* descriptor index for the second source (if relevant) */ + graphene_rect_t source_rect; /* area that source maps to */ + graphene_rect_t source2_rect; /* area that source2 maps to */ }; struct _GskVulkanOpText @@ -660,88 +662,117 @@ gsk_vulkan_render_pass_add (GskVulkanRenderPass *self, } static GskVulkanImage * -gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self, - GskVulkanRender *render, - GskVulkanUploader *uploader, - GskRenderNode *node, - const graphene_rect_t *bounds) +gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self, + GskVulkanRender *render, + GskVulkanUploader *uploader, + GskRenderNode *node, + graphene_rect_t *bounds, + GskVulkanClip *current_clip, + graphene_rect_t *tex_rect) { GskVulkanImage *result; cairo_surface_t *surface; cairo_t *cr; - if (graphene_rect_equal (bounds, &node->bounds)) + switch (gsk_render_node_get_node_type (node)) { - switch (gsk_render_node_get_node_type (node)) + case GSK_TEXTURE_NODE: + if (graphene_rect_equal (bounds, &node->bounds)) { - case GSK_TEXTURE_NODE: result = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)), gsk_texture_node_get_texture (node), uploader); gsk_vulkan_render_add_cleanup_image (render, result); + *tex_rect = GRAPHENE_RECT_INIT(0, 0, 1, 1); return result; + } + break; - case GSK_CAIRO_NODE: + case GSK_CAIRO_NODE: + if (graphene_rect_equal (bounds, &node->bounds)) + { surface = cairo_surface_reference (gsk_cairo_node_get_surface (node)); goto got_surface; + } + break; - default: ; - { - VkSemaphore semaphore; - graphene_rect_t view; - cairo_region_t *clip; - GskVulkanRenderPass *pass; + default: ; + { + VkSemaphore semaphore; + graphene_rect_t view; + cairo_region_t *clip; + GskVulkanRenderPass *pass; + graphene_rect_t clipped; + + if (current_clip) + graphene_rect_intersection (¤t_clip->rect.bounds, bounds, &clipped); + else + clipped = *bounds; - graphene_matrix_transform_bounds (&self->mv, bounds, &view); + if (clipped.size.width == 0 || clipped.size.height == 0) + return NULL; - result = gsk_vulkan_image_new_for_texture (self->vulkan, - ceil (view.size.width), - ceil (view.size.height)); + 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); #ifdef G_ENABLE_DEBUG - { - GskProfiler *profiler = gsk_renderer_get_profiler (gsk_vulkan_render_get_renderer (render)); - gsk_profiler_counter_add (profiler, - self->texture_pixels, - ceil (view.size.width) * ceil (view.size.height)); - } + { + 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); + } #endif - 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, - 1, - &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); - - return result; - } - } - } + 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; + } + } GSK_NOTE (FALLBACK, g_print ("Node as texture not implemented for this case. Using %gx%g fallback surface\n", ceil (bounds->size.width), @@ -777,6 +808,8 @@ got_surface: gsk_vulkan_render_add_cleanup_image (render, result); + *tex_rect = GRAPHENE_RECT_INIT(0, 0, 1, 1); + return result; } @@ -842,6 +875,8 @@ gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self, cairo_image_surface_get_height (surface), cairo_image_surface_get_stride (surface)); + op->source_rect = GRAPHENE_RECT_INIT(0, 0, 1, 1); + cairo_surface_destroy (surface); gsk_vulkan_render_add_cleanup_image (render, op->source); @@ -854,6 +889,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, { GskVulkanOp *op; guint i; + const GskVulkanClip *clip = NULL; for (i = 0; i < self->render_ops->len; i++) { @@ -877,6 +913,8 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface), cairo_image_surface_get_stride (surface)); + op->render.source_rect = GRAPHENE_RECT_INIT(0, 0, 1, 1); + gsk_vulkan_render_add_cleanup_image (render, op->render.source); } break; @@ -896,6 +934,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, op->render.source = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)), gsk_texture_node_get_texture (op->render.node), uploader); + op->render.source_rect = GRAPHENE_RECT_INIT(0, 0, 1, 1); gsk_vulkan_render_add_cleanup_image (render, op->render.source); } break; @@ -908,20 +947,24 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, render, uploader, child, - &child->bounds); + &child->bounds, + clip, + &op->render.source_rect); } break; case GSK_VULKAN_OP_REPEAT: { GskRenderNode *child = gsk_repeat_node_get_child (op->render.node); - const graphene_rect_t *child_bounds = gsk_repeat_node_peek_child_bounds (op->render.node); + const graphene_rect_t *bounds = gsk_repeat_node_peek_child_bounds (op->render.node); op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self, render, uploader, child, - child_bounds); + bounds, + NULL, + &op->render.source_rect); } break; @@ -933,7 +976,9 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, render, uploader, child, - &child->bounds); + &child->bounds, + clip, + &op->render.source_rect); } break; @@ -945,7 +990,9 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, render, uploader, child, - &child->bounds); + &child->bounds, + clip, + &op->render.source_rect); } break; @@ -958,12 +1005,16 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, render, uploader, start, - &start->bounds); + &start->bounds, + clip, + &op->render.source_rect); op->render.source2 = gsk_vulkan_render_pass_get_node_as_texture (self, render, uploader, end, - &end->bounds); + &end->bounds, + clip, + &op->render.source2_rect); } break; @@ -976,20 +1027,27 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, render, uploader, top, - &top->bounds); + &top->bounds, + clip, + &op->render.source_rect); op->render.source2 = gsk_vulkan_render_pass_get_node_as_texture (self, render, uploader, bottom, - &bottom->bounds); + &bottom->bounds, + clip, + &op->render.source2_rect); } break; + case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: + clip = &op->constants.constants.clip; + break; + default: g_assert_not_reached (); case GSK_VULKAN_OP_COLOR: case GSK_VULKAN_OP_LINEAR_GRADIENT: - case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: case GSK_VULKAN_OP_BORDER: case GSK_VULKAN_OP_INSET_SHADOW: case GSK_VULKAN_OP_OUTSET_SHADOW: @@ -1115,20 +1173,18 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, gsk_vulkan_texture_pipeline_collect_vertex_data (GSK_VULKAN_TEXTURE_PIPELINE (op->render.pipeline), data + n_bytes + offset, &op->render.node->bounds, - &op->render.node->bounds); + &op->render.source_rect); n_bytes += op->render.vertex_count; } break; case GSK_VULKAN_OP_REPEAT: { - const graphene_rect_t *child_bounds = gsk_repeat_node_peek_child_bounds (op->render.node); - 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, - child_bounds); + &op->render.source_rect); n_bytes += op->render.vertex_count; } break; @@ -1198,18 +1254,21 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, { graphene_matrix_t color_matrix; graphene_vec4_t color_offset; + graphene_matrix_init_from_float (&color_matrix, (float[16]) { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, 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); 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, + &op->render.source_rect, &color_matrix, &color_offset); n_bytes += op->render.vertex_count; @@ -1222,6 +1281,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, gsk_vulkan_blur_pipeline_collect_vertex_data (GSK_VULKAN_BLUR_PIPELINE (op->render.pipeline), data + n_bytes + offset, &op->render.node->bounds, + &op->render.source_rect, gsk_blur_node_get_radius (op->render.node)); n_bytes += op->render.vertex_count; } @@ -1233,6 +1293,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, gsk_vulkan_effect_pipeline_collect_vertex_data (GSK_VULKAN_EFFECT_PIPELINE (op->render.pipeline), data + n_bytes + offset, &op->render.node->bounds, + &op->render.source_rect, 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; @@ -1283,15 +1344,12 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, case GSK_VULKAN_OP_CROSS_FADE: { - GskRenderNode *start = gsk_cross_fade_node_get_start_child (op->render.node); - GskRenderNode *end = gsk_cross_fade_node_get_end_child (op->render.node); - op->render.vertex_offset = offset + n_bytes; gsk_vulkan_cross_fade_pipeline_collect_vertex_data (GSK_VULKAN_CROSS_FADE_PIPELINE (op->render.pipeline), data + n_bytes + offset, &op->render.node->bounds, - &start->bounds, - &end->bounds, + &op->render.source_rect, + &op->render.source2_rect, gsk_cross_fade_node_get_progress (op->render.node)); n_bytes += op->render.vertex_count; } @@ -1299,15 +1357,12 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, 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); - op->render.vertex_offset = offset + n_bytes; gsk_vulkan_blend_mode_pipeline_collect_vertex_data (GSK_VULKAN_BLEND_MODE_PIPELINE (op->render.pipeline), data + n_bytes + offset, &op->render.node->bounds, - &top->bounds, - &bottom->bounds, + &op->render.source_rect, + &op->render.source2_rect, gsk_blend_node_get_blend_mode (op->render.node)); n_bytes += op->render.vertex_count; } @@ -1381,11 +1436,13 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self, case GSK_VULKAN_OP_OPACITY: case GSK_VULKAN_OP_BLUR: case GSK_VULKAN_OP_COLOR_MATRIX: - op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source, FALSE); + if (op->render.source) + op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source, FALSE); break; case GSK_VULKAN_OP_REPEAT: - op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source, TRUE); + if (op->render.source) + op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source, TRUE); break; case GSK_VULKAN_OP_TEXT: @@ -1395,8 +1452,11 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self, case GSK_VULKAN_OP_CROSS_FADE: case GSK_VULKAN_OP_BLEND_MODE: - 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); + 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); + } break; default: @@ -1441,6 +1501,8 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, case GSK_VULKAN_OP_SURFACE: case GSK_VULKAN_OP_TEXTURE: case GSK_VULKAN_OP_REPEAT: + if (!op->render.source) + continue; if (current_pipeline != op->render.pipeline) { current_pipeline = op->render.pipeline; @@ -1541,6 +1603,8 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, case GSK_VULKAN_OP_OPACITY: case GSK_VULKAN_OP_COLOR_MATRIX: + if (!op->render.source) + continue; if (current_pipeline != op->render.pipeline) { current_pipeline = op->render.pipeline; @@ -1574,6 +1638,8 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, break; case GSK_VULKAN_OP_BLUR: + if (!op->render.source) + continue; if (current_pipeline != op->render.pipeline) { current_pipeline = op->render.pipeline; @@ -1707,6 +1773,8 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, break; case GSK_VULKAN_OP_CROSS_FADE: + if (!op->render.source || !op->render.source2) + continue; if (current_pipeline != op->render.pipeline) { current_pipeline = op->render.pipeline; @@ -1741,6 +1809,8 @@ gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, break; case GSK_VULKAN_OP_BLEND_MODE: + if (!op->render.source || !op->render.source2) + continue; if (current_pipeline != op->render.pipeline) { current_pipeline = op->render.pipeline; diff --git a/gsk/gskvulkantexturepipeline.c b/gsk/gskvulkantexturepipeline.c index 83dae29adc..9db719093b 100644 --- a/gsk/gskvulkantexturepipeline.c +++ b/gsk/gskvulkantexturepipeline.c @@ -102,10 +102,10 @@ gsk_vulkan_texture_pipeline_collect_vertex_data (GskVulkanTexturePipeline *pipel instance->rect[1] = rect->origin.y; instance->rect[2] = rect->size.width; instance->rect[3] = rect->size.height; - instance->tex_rect[0] = (rect->origin.x - tex_rect->origin.x)/tex_rect->size.width; - instance->tex_rect[1] = (rect->origin.y - tex_rect->origin.y)/tex_rect->size.height; - instance->tex_rect[2] = (rect->size.width + rect->origin.x - tex_rect->origin.x)/tex_rect->size.width; - instance->tex_rect[3] = (rect->size.height + rect->origin.y - tex_rect->origin.y)/tex_rect->size.height; + instance->tex_rect[0] = tex_rect->origin.x; + instance->tex_rect[1] = tex_rect->origin.y; + instance->tex_rect[2] = tex_rect->size.width; + instance->tex_rect[3] = tex_rect->size.height; } gsize |