[gtk+] vulkan: Only render minimal region
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] vulkan: Only render minimal region
- Date: Mon, 26 Dec 2016 23:50:34 +0000 (UTC)
commit a5f8a74ec1d7390c81f4cbae9b84ca942b879233
Author: Benjamin Otte <otte redhat com>
Date: Tue Dec 27 00:18:52 2016 +0100
vulkan: Only render minimal region
It's faster to render once for every rectangle in the clip region than
rendering the outline of the clip region.
Especially because this reduces the time necessary to build up the frame
data.
In widget-factory (where we have 3 rectangles), this leads to a 5x
speedup in the rendering time rendering alone.
Snapshotting time goes from 10ms to ~1ms, which is another huge
improvement.
gsk/gskvulkanrender.c | 88 +++++++++++++++++++++++++----------------------
gsk/gskvulkanrenderer.c | 16 +-------
2 files changed, 49 insertions(+), 55 deletions(-)
---
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index a2968cc..12dac4d 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -26,7 +26,7 @@ struct _GskVulkanRender
graphene_matrix_t mvp;
int scale_factor;
VkRect2D viewport;
- VkRect2D scissor;
+ cairo_region_t *clip;
GHashTable *framebuffers;
GskVulkanCommandPool *command_pool;
@@ -49,32 +49,31 @@ struct _GskVulkanRender
};
static void
-gsk_vulkan_render_compute_mvp (GskVulkanRender *self,
- const graphene_rect_t *rect)
+gsk_vulkan_render_setup (GskVulkanRender *self,
+ GskVulkanImage *target,
+ const graphene_rect_t *rect)
{
GdkWindow *window = gsk_renderer_get_window (self->renderer);
graphene_matrix_t modelview, projection;
- cairo_rectangle_int_t extents;
+
+ self->target = g_object_ref (target);
if (rect)
{
- self->scissor = (VkRect2D) { { 0, 0 }, { rect->size.width, rect->size.height } };
self->viewport = (VkRect2D) { { rect->origin.x, rect->origin.y }, { rect->size.width,
rect->size.height } };
self->scale_factor = 1;
+ self->clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
+ 0, 0,
+ gsk_vulkan_image_get_width (target),
gsk_vulkan_image_get_height (target)
+ });
}
else
{
- cairo_region_get_extents (gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context
(self->renderer)),
- &extents);
-
self->scale_factor = gsk_renderer_get_scale_factor (self->renderer);
self->viewport.offset = (VkOffset2D) { 0, 0 };
self->viewport.extent.width = gdk_window_get_width (window) * self->scale_factor;
self->viewport.extent.height = gdk_window_get_height (window) * self->scale_factor;
- self->scissor.offset.x = extents.x * self->scale_factor;
- self->scissor.offset.y = extents.y * self->scale_factor;
- self->scissor.extent.width = extents.width * self->scale_factor;
- self->scissor.extent.height = extents.height * self->scale_factor;
+ self->clip = gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (self->renderer));
}
graphene_matrix_init_scale (&modelview, self->scale_factor, self->scale_factor, 1.0);
@@ -464,6 +463,7 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
GskVulkanBuffer *buffer;
VkCommandBuffer command_buffer;
GSList *l;
+ guint i;
gsk_vulkan_render_prepare_descriptor_sets (self, sampler);
@@ -483,36 +483,43 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
.maxDepth = 1
});
- vkCmdSetScissor (command_buffer,
- 0,
- 1,
- &self->scissor);
-
- vkCmdBeginRenderPass (command_buffer,
- &(VkRenderPassBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
- .renderPass = self->render_pass,
- .framebuffer = gsk_vulkan_render_get_framebuffer (self, self->target),
- .renderArea = {
- { 0, 0 },
- {
- gsk_vulkan_image_get_width (self->target),
- gsk_vulkan_image_get_height (self->target)
+ 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 (self, 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 } } }
}
},
- .clearValueCount = 1,
- .pClearValues = (VkClearValue [1]) {
- { .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } }
- }
- },
- VK_SUBPASS_CONTENTS_INLINE);
+ VK_SUBPASS_CONTENTS_INLINE);
- for (l = self->render_passes; l; l = l->next)
- {
- gsk_vulkan_render_pass_draw (l->data, self, buffer, self->layout, command_buffer);
- }
+ for (l = self->render_passes; l; l = l->next)
+ {
+ gsk_vulkan_render_pass_draw (l->data, self, buffer, self->layout, command_buffer);
+ }
- vkCmdEndRenderPass (command_buffer);
+ vkCmdEndRenderPass (command_buffer);
+ }
gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, self->fence);
@@ -563,6 +570,7 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self)
g_slist_free_full (self->cleanup_images, g_object_unref);
self->cleanup_images = NULL;
+ g_clear_pointer (&self->clip, cairo_region_destroy);
g_clear_object (&self->target);
}
@@ -631,9 +639,7 @@ gsk_vulkan_render_reset (GskVulkanRender *self,
{
gsk_vulkan_render_cleanup (self);
- self->target = g_object_ref (target);
-
- gsk_vulkan_render_compute_mvp (self, rect);
+ gsk_vulkan_render_setup (self, target, rect);
}
GskRenderer *
diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c
index 747ed09..4ae0f4d 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -257,23 +257,11 @@ gsk_vulkan_renderer_begin_draw_frame (GskRenderer *renderer,
const cairo_region_t *region)
{
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
- cairo_region_t *whole_window;
GdkDrawingContext *result;
- GdkWindow *window;
-
- window = gsk_renderer_get_window (renderer);
-
- whole_window = cairo_region_create_rectangle (&(GdkRectangle) {
- 0, 0,
- gdk_window_get_width (window),
- gdk_window_get_height (window)
- });
- result = gdk_window_begin_draw_frame (window,
+ result = gdk_window_begin_draw_frame (gsk_renderer_get_window (renderer),
GDK_DRAW_CONTEXT (self->vulkan),
- whole_window);
-
- cairo_region_destroy (whole_window);
+ region);
return result;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]