forked from AuroraMiddleware/gtk
gsk: Add GskVulkanClip
This is now tracking the clips added by the clip nodes. If any particular node can't deal with a clip, it falls back to Cairo rendering. But if it can, it will render it directly.
This commit is contained in:
parent
1d84555729
commit
2bca24c455
@ -26,6 +26,7 @@ if HAVE_VULKAN
|
|||||||
gsk_private_vulkan_source_h = \
|
gsk_private_vulkan_source_h = \
|
||||||
gskvulkanblendpipelineprivate.h \
|
gskvulkanblendpipelineprivate.h \
|
||||||
gskvulkanbufferprivate.h \
|
gskvulkanbufferprivate.h \
|
||||||
|
gskvulkanclipprivate.h \
|
||||||
gskvulkancolorpipelineprivate.h \
|
gskvulkancolorpipelineprivate.h \
|
||||||
gskvulkancommandpoolprivate.h \
|
gskvulkancommandpoolprivate.h \
|
||||||
gskvulkanimageprivate.h \
|
gskvulkanimageprivate.h \
|
||||||
@ -39,6 +40,7 @@ gsk_private_vulkan_source_h = \
|
|||||||
gsk_private_vulkan_source_c = \
|
gsk_private_vulkan_source_c = \
|
||||||
gskvulkanblendpipeline.c \
|
gskvulkanblendpipeline.c \
|
||||||
gskvulkanbuffer.c \
|
gskvulkanbuffer.c \
|
||||||
|
gskvulkanclip.c \
|
||||||
gskvulkancolorpipeline.c \
|
gskvulkancolorpipeline.c \
|
||||||
gskvulkancommandpool.c \
|
gskvulkancommandpool.c \
|
||||||
gskvulkanimage.c \
|
gskvulkanimage.c \
|
||||||
|
@ -277,6 +277,21 @@ gsk_rounded_rect_shrink (GskRoundedRect *self,
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX: Fina a better name */
|
||||||
|
gboolean
|
||||||
|
gsk_rounded_rect_is_circular (const GskRoundedRect *self)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (self->corner[i].width != self->corner[i].height)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gsk_rounded_rect_is_rectilinear:
|
* gsk_rounded_rect_is_rectilinear:
|
||||||
* @self: the #GskRoundedRect to check
|
* @self: the #GskRoundedRect to check
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
gboolean gsk_rounded_rect_is_circular (const GskRoundedRect *self);
|
||||||
|
|
||||||
void gsk_rounded_rect_path (const GskRoundedRect *self,
|
void gsk_rounded_rect_path (const GskRoundedRect *self,
|
||||||
cairo_t *cr);
|
cairo_t *cr);
|
||||||
|
|
||||||
|
151
gsk/gskvulkanclip.c
Normal file
151
gsk/gskvulkanclip.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gskvulkanclipprivate.h"
|
||||||
|
|
||||||
|
#include "gskroundedrectprivate.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
gsk_vulkan_clip_init_empty (GskVulkanClip *clip,
|
||||||
|
const graphene_rect_t *rect)
|
||||||
|
{
|
||||||
|
clip->type = GSK_VULKAN_CLIP_NONE;
|
||||||
|
gsk_rounded_rect_init_from_rect (&clip->rect, rect, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gsk_vulkan_clip_init_copy (GskVulkanClip *self,
|
||||||
|
const GskVulkanClip *src)
|
||||||
|
{
|
||||||
|
self->type = src->type;
|
||||||
|
gsk_rounded_rect_init_copy (&self->rect, &src->rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gsk_vulkan_clip_intersect_rect (GskVulkanClip *dest,
|
||||||
|
const GskVulkanClip *src,
|
||||||
|
const graphene_rect_t *rect)
|
||||||
|
{
|
||||||
|
if (graphene_rect_contains_rect (rect, &src->rect.bounds))
|
||||||
|
{
|
||||||
|
gsk_vulkan_clip_init_copy (dest, src);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (!graphene_rect_intersection (rect, &src->rect.bounds, NULL))
|
||||||
|
{
|
||||||
|
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (src->type)
|
||||||
|
{
|
||||||
|
case GSK_VULKAN_CLIP_ALL_CLIPPED:
|
||||||
|
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_VULKAN_CLIP_NONE:
|
||||||
|
gsk_vulkan_clip_init_copy (dest, src);
|
||||||
|
if (graphene_rect_intersection (&dest->rect.bounds, rect, &dest->rect.bounds))
|
||||||
|
dest->type = GSK_VULKAN_CLIP_RECT;
|
||||||
|
else
|
||||||
|
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_VULKAN_CLIP_RECT:
|
||||||
|
gsk_vulkan_clip_init_copy (dest, src);
|
||||||
|
if (!graphene_rect_intersection (&dest->rect.bounds, rect, &dest->rect.bounds))
|
||||||
|
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
|
||||||
|
case GSK_VULKAN_CLIP_ROUNDED:
|
||||||
|
if (gsk_rounded_rect_contains_rect (&src->rect, rect))
|
||||||
|
{
|
||||||
|
dest->type = GSK_VULKAN_CLIP_RECT;
|
||||||
|
gsk_rounded_rect_init_from_rect (&dest->rect, rect, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* some points of rect are inside src's rounded rect,
|
||||||
|
* some are outside. */
|
||||||
|
/* XXX: If the 2 rects don't intersect on rounded corners,
|
||||||
|
* we could actually compute a new clip here.
|
||||||
|
*/
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gsk_vulkan_clip_intersect_rounded_rect (GskVulkanClip *dest,
|
||||||
|
const GskVulkanClip *src,
|
||||||
|
const GskRoundedRect *rounded)
|
||||||
|
{
|
||||||
|
if (gsk_rounded_rect_contains_rect (rounded, &src->rect.bounds))
|
||||||
|
{
|
||||||
|
gsk_vulkan_clip_init_copy (dest, src);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (!graphene_rect_intersection (&rounded->bounds, &src->rect.bounds, NULL))
|
||||||
|
{
|
||||||
|
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (src->type)
|
||||||
|
{
|
||||||
|
case GSK_VULKAN_CLIP_ALL_CLIPPED:
|
||||||
|
dest->type = GSK_VULKAN_CLIP_ALL_CLIPPED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_VULKAN_CLIP_NONE:
|
||||||
|
dest->type = gsk_rounded_rect_is_circular (&dest->rect) ? GSK_VULKAN_CLIP_ROUNDED_CIRCULAR : GSK_VULKAN_CLIP_ROUNDED;
|
||||||
|
gsk_rounded_rect_init_copy (&dest->rect, rounded);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GSK_VULKAN_CLIP_RECT:
|
||||||
|
if (graphene_rect_contains_rect (&src->rect.bounds, &rounded->bounds))
|
||||||
|
{
|
||||||
|
dest->type = gsk_rounded_rect_is_circular (&dest->rect) ? GSK_VULKAN_CLIP_ROUNDED_CIRCULAR : GSK_VULKAN_CLIP_ROUNDED;
|
||||||
|
gsk_rounded_rect_init_copy (&dest->rect, rounded);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
/* some points of rect are inside src's rounded rect,
|
||||||
|
* some are outside. */
|
||||||
|
/* XXX: If the 2 rects don't intersect on rounded corners,
|
||||||
|
* we could actually compute a new clip here.
|
||||||
|
*/
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
|
||||||
|
case GSK_VULKAN_CLIP_ROUNDED:
|
||||||
|
/* XXX: improve */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gsk_vulkan_clip_contains_rect (const GskVulkanClip *self,
|
||||||
|
const graphene_rect_t *rect)
|
||||||
|
{
|
||||||
|
switch (self->type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
case GSK_VULKAN_CLIP_ALL_CLIPPED:
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
case GSK_VULKAN_CLIP_NONE:
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case GSK_VULKAN_CLIP_RECT:
|
||||||
|
return graphene_rect_contains_rect (&self->rect.bounds, rect);
|
||||||
|
|
||||||
|
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
|
||||||
|
case GSK_VULKAN_CLIP_ROUNDED:
|
||||||
|
return gsk_rounded_rect_contains_rect (&self->rect, rect);
|
||||||
|
}
|
||||||
|
}
|
53
gsk/gskvulkanclipprivate.h
Normal file
53
gsk/gskvulkanclipprivate.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef __GSK_VULKAN_CLIP_PRIVATE_H__
|
||||||
|
#define __GSK_VULKAN_CLIP_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <gdk/gdk.h>
|
||||||
|
#include <graphene.h>
|
||||||
|
#include <gsk/gskroundedrect.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* The whole area is clipped, no drawing is necessary.
|
||||||
|
* This can't be handled by return values because for return
|
||||||
|
* values we return if clips could even be computed.
|
||||||
|
*/
|
||||||
|
GSK_VULKAN_CLIP_ALL_CLIPPED,
|
||||||
|
/* No clipping is necesary, but the clip rect is set
|
||||||
|
* to the actual bounds of the underlying framebuffer
|
||||||
|
*/
|
||||||
|
GSK_VULKAN_CLIP_NONE,
|
||||||
|
/* The clip is a rectangular area */
|
||||||
|
GSK_VULKAN_CLIP_RECT,
|
||||||
|
/* The clip is a rounded rectangle, and for every corner
|
||||||
|
* corner.width == corner.height is true
|
||||||
|
*/
|
||||||
|
GSK_VULKAN_CLIP_ROUNDED_CIRCULAR,
|
||||||
|
/* The clip is a rounded rectangle */
|
||||||
|
GSK_VULKAN_CLIP_ROUNDED
|
||||||
|
} GskVulkanClipComplexity;
|
||||||
|
|
||||||
|
typedef struct _GskVulkanClip GskVulkanClip;
|
||||||
|
|
||||||
|
struct _GskVulkanClip
|
||||||
|
{
|
||||||
|
GskVulkanClipComplexity type;
|
||||||
|
GskRoundedRect rect;
|
||||||
|
};
|
||||||
|
|
||||||
|
void gsk_vulkan_clip_init_empty (GskVulkanClip *clip,
|
||||||
|
const graphene_rect_t *rect);
|
||||||
|
|
||||||
|
gboolean gsk_vulkan_clip_intersect_rect (GskVulkanClip *dest,
|
||||||
|
const GskVulkanClip *src,
|
||||||
|
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
gboolean gsk_vulkan_clip_intersect_rounded_rect (GskVulkanClip *dest,
|
||||||
|
const GskVulkanClip *src,
|
||||||
|
const GskRoundedRect *rounded) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
gboolean gsk_vulkan_clip_contains_rect (const GskVulkanClip *self,
|
||||||
|
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSK_VULKAN_CLIP_PRIVATE_H__ */
|
@ -243,7 +243,14 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
|
|||||||
|
|
||||||
self->render_passes = g_slist_prepend (self->render_passes, pass);
|
self->render_passes = g_slist_prepend (self->render_passes, pass);
|
||||||
|
|
||||||
gsk_vulkan_render_pass_add (pass, self, &self->mvp, node);
|
gsk_vulkan_render_pass_add (pass,
|
||||||
|
self,
|
||||||
|
&self->mvp,
|
||||||
|
&GRAPHENE_RECT_INIT (
|
||||||
|
self->viewport.offset.x, self->viewport.offset.y,
|
||||||
|
self->viewport.extent.width, self->viewport.extent.height
|
||||||
|
),
|
||||||
|
node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
#include "gskvulkanrenderpassprivate.h"
|
#include "gskvulkanrenderpassprivate.h"
|
||||||
|
|
||||||
#include "gskvulkanblendpipelineprivate.h"
|
|
||||||
#include "gskvulkancolorpipelineprivate.h"
|
|
||||||
#include "gskvulkanimageprivate.h"
|
|
||||||
#include "gskrendernodeprivate.h"
|
#include "gskrendernodeprivate.h"
|
||||||
#include "gskrenderer.h"
|
#include "gskrenderer.h"
|
||||||
|
#include "gskroundedrectprivate.h"
|
||||||
|
#include "gskvulkanblendpipelineprivate.h"
|
||||||
|
#include "gskvulkanclipprivate.h"
|
||||||
|
#include "gskvulkancolorpipelineprivate.h"
|
||||||
|
#include "gskvulkanimageprivate.h"
|
||||||
#include "gskvulkanpushconstantsprivate.h"
|
#include "gskvulkanpushconstantsprivate.h"
|
||||||
#include "gskvulkanrendererprivate.h"
|
#include "gskvulkanrendererprivate.h"
|
||||||
|
|
||||||
@ -17,6 +19,8 @@ typedef struct _GskVulkanOpPushConstants GskVulkanOpPushConstants;
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
/* GskVulkanOpRender */
|
/* GskVulkanOpRender */
|
||||||
GSK_VULKAN_OP_FALLBACK,
|
GSK_VULKAN_OP_FALLBACK,
|
||||||
|
GSK_VULKAN_OP_FALLBACK_CLIP,
|
||||||
|
GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP,
|
||||||
GSK_VULKAN_OP_SURFACE,
|
GSK_VULKAN_OP_SURFACE,
|
||||||
GSK_VULKAN_OP_TEXTURE,
|
GSK_VULKAN_OP_TEXTURE,
|
||||||
GSK_VULKAN_OP_COLOR,
|
GSK_VULKAN_OP_COLOR,
|
||||||
@ -29,6 +33,7 @@ struct _GskVulkanOpRender
|
|||||||
GskVulkanOpType type;
|
GskVulkanOpType type;
|
||||||
GskRenderNode *node; /* node that's the source of this op */
|
GskRenderNode *node; /* node that's the source of this op */
|
||||||
GskVulkanPipeline *pipeline; /* pipeline to use */
|
GskVulkanPipeline *pipeline; /* pipeline to use */
|
||||||
|
GskRoundedRect clip; /* clip rect (or random memory if not relevant) */
|
||||||
GskVulkanImage *source; /* source image to render */
|
GskVulkanImage *source; /* source image to render */
|
||||||
gsize vertex_offset; /* offset into vertex buffer */
|
gsize vertex_offset; /* offset into vertex buffer */
|
||||||
gsize vertex_count; /* number of vertices */
|
gsize vertex_count; /* number of vertices */
|
||||||
@ -81,6 +86,7 @@ void
|
|||||||
gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
||||||
GskVulkanRender *render,
|
GskVulkanRender *render,
|
||||||
const GskVulkanPushConstants *constants,
|
const GskVulkanPushConstants *constants,
|
||||||
|
const GskVulkanClip *clip,
|
||||||
GskRenderNode *node)
|
GskRenderNode *node)
|
||||||
{
|
{
|
||||||
GskVulkanOp op = {
|
GskVulkanOp op = {
|
||||||
@ -92,34 +98,35 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
|||||||
{
|
{
|
||||||
case GSK_NOT_A_RENDER_NODE:
|
case GSK_NOT_A_RENDER_NODE:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
break;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
op.type = GSK_VULKAN_OP_FALLBACK;
|
goto fallback;
|
||||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
|
||||||
g_array_append_val (self->render_ops, op);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GSK_CAIRO_NODE:
|
case GSK_CAIRO_NODE:
|
||||||
if (gsk_cairo_node_get_surface (node) != NULL)
|
if (gsk_cairo_node_get_surface (node) == NULL)
|
||||||
{
|
return;
|
||||||
op.type = GSK_VULKAN_OP_SURFACE;
|
if (!gsk_vulkan_clip_contains_rect (clip, &node->bounds))
|
||||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
goto fallback;
|
||||||
g_array_append_val (self->render_ops, op);
|
op.type = GSK_VULKAN_OP_SURFACE;
|
||||||
}
|
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
||||||
break;
|
g_array_append_val (self->render_ops, op);
|
||||||
|
return;
|
||||||
|
|
||||||
case GSK_TEXTURE_NODE:
|
case GSK_TEXTURE_NODE:
|
||||||
|
if (!gsk_vulkan_clip_contains_rect (clip, &node->bounds))
|
||||||
|
goto fallback;
|
||||||
op.type = GSK_VULKAN_OP_TEXTURE;
|
op.type = GSK_VULKAN_OP_TEXTURE;
|
||||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
||||||
g_array_append_val (self->render_ops, op);
|
g_array_append_val (self->render_ops, op);
|
||||||
break;
|
return;
|
||||||
|
|
||||||
case GSK_COLOR_NODE:
|
case GSK_COLOR_NODE:
|
||||||
|
if (!gsk_vulkan_clip_contains_rect (clip, &node->bounds))
|
||||||
|
goto fallback;
|
||||||
op.type = GSK_VULKAN_OP_COLOR;
|
op.type = GSK_VULKAN_OP_COLOR;
|
||||||
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_COLOR);
|
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_COLOR);
|
||||||
g_array_append_val (self->render_ops, op);
|
g_array_append_val (self->render_ops, op);
|
||||||
break;
|
return;
|
||||||
|
|
||||||
case GSK_CONTAINER_NODE:
|
case GSK_CONTAINER_NODE:
|
||||||
{
|
{
|
||||||
@ -127,13 +134,19 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
|||||||
|
|
||||||
for (i = 0; i < gsk_container_node_get_n_children (node); i++)
|
for (i = 0; i < gsk_container_node_get_n_children (node); i++)
|
||||||
{
|
{
|
||||||
gsk_vulkan_render_pass_add_node (self, render, constants, gsk_container_node_get_child (node, i));
|
gsk_vulkan_render_pass_add_node (self, render, constants, clip, gsk_container_node_get_child (node, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
return;
|
||||||
|
|
||||||
case GSK_TRANSFORM_NODE:
|
case GSK_TRANSFORM_NODE:
|
||||||
{
|
{
|
||||||
graphene_matrix_t transform;
|
graphene_matrix_t transform;
|
||||||
|
GskVulkanClip new_clip;
|
||||||
|
graphene_rect_t rect;
|
||||||
|
|
||||||
|
if (!gsk_vulkan_clip_contains_rect (clip, &node->bounds))
|
||||||
|
goto fallback;
|
||||||
|
|
||||||
gsk_transform_node_get_transform (node, &transform);
|
gsk_transform_node_get_transform (node, &transform);
|
||||||
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
|
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
|
||||||
@ -141,28 +154,86 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
|
|||||||
gsk_vulkan_push_constants_multiply_mvp (&op.constants.constants, &transform);
|
gsk_vulkan_push_constants_multiply_mvp (&op.constants.constants, &transform);
|
||||||
g_array_append_val (self->render_ops, op);
|
g_array_append_val (self->render_ops, op);
|
||||||
|
|
||||||
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, gsk_transform_node_get_child (node));
|
graphene_matrix_transform_bounds (&transform, &clip->rect.bounds, &rect);
|
||||||
|
gsk_vulkan_clip_init_empty (&new_clip, &rect);
|
||||||
|
|
||||||
|
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, &new_clip, gsk_transform_node_get_child (node));
|
||||||
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
|
gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
|
||||||
g_array_append_val (self->render_ops, op);
|
g_array_append_val (self->render_ops, op);
|
||||||
}
|
}
|
||||||
break;
|
return;
|
||||||
|
|
||||||
|
case GSK_CLIP_NODE:
|
||||||
|
{
|
||||||
|
GskVulkanClip new_clip;
|
||||||
|
|
||||||
|
if (!gsk_vulkan_clip_intersect_rect (&new_clip, clip, gsk_clip_node_peek_clip (node)))
|
||||||
|
goto fallback;
|
||||||
|
if (new_clip.type == GSK_VULKAN_CLIP_ALL_CLIPPED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, &new_clip, gsk_clip_node_get_child (node));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GSK_ROUNDED_CLIP_NODE:
|
||||||
|
{
|
||||||
|
GskVulkanClip new_clip;
|
||||||
|
|
||||||
|
if (!gsk_vulkan_clip_intersect_rounded_rect (&new_clip, clip, gsk_rounded_clip_node_peek_clip (node)))
|
||||||
|
goto fallback;
|
||||||
|
if (new_clip.type == GSK_VULKAN_CLIP_ALL_CLIPPED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, &new_clip, gsk_rounded_clip_node_get_child (node));
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
|
return;
|
||||||
|
|
||||||
|
fallback:
|
||||||
|
switch (clip->type)
|
||||||
|
{
|
||||||
|
case GSK_VULKAN_CLIP_NONE:
|
||||||
|
op.type = GSK_VULKAN_OP_FALLBACK;
|
||||||
|
break;
|
||||||
|
case GSK_VULKAN_CLIP_RECT:
|
||||||
|
op.type = GSK_VULKAN_OP_FALLBACK_CLIP;
|
||||||
|
gsk_rounded_rect_init_copy (&op.render.clip, &clip->rect);
|
||||||
|
break;
|
||||||
|
case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
|
||||||
|
case GSK_VULKAN_CLIP_ROUNDED:
|
||||||
|
op.type = GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP;
|
||||||
|
gsk_rounded_rect_init_copy (&op.render.clip, &clip->rect);
|
||||||
|
break;
|
||||||
|
case GSK_VULKAN_CLIP_ALL_CLIPPED:
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
|
||||||
|
g_array_append_val (self->render_ops, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
|
gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
|
||||||
GskVulkanRender *render,
|
GskVulkanRender *render,
|
||||||
const graphene_matrix_t *mvp,
|
const graphene_matrix_t *mvp,
|
||||||
|
const graphene_rect_t *viewport,
|
||||||
GskRenderNode *node)
|
GskRenderNode *node)
|
||||||
{
|
{
|
||||||
GskVulkanOp op = { 0, };
|
GskVulkanOp op = { 0, };
|
||||||
|
GskVulkanClip clip;
|
||||||
|
|
||||||
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
|
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
|
||||||
gsk_vulkan_push_constants_init (&op.constants.constants, mvp);
|
gsk_vulkan_push_constants_init (&op.constants.constants, mvp);
|
||||||
g_array_append_val (self->render_ops, op);
|
g_array_append_val (self->render_ops, op);
|
||||||
|
|
||||||
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, node);
|
gsk_vulkan_clip_init_empty (&clip, viewport);
|
||||||
|
|
||||||
|
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, &clip, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -177,12 +248,30 @@ gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderPass *self,
|
|||||||
|
|
||||||
node = op->node;
|
node = op->node;
|
||||||
|
|
||||||
|
/* XXX: We could intersect bounds with clip bounds here */
|
||||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||||
ceil (node->bounds.size.width),
|
ceil (node->bounds.size.width),
|
||||||
ceil (node->bounds.size.height));
|
ceil (node->bounds.size.height));
|
||||||
cr = cairo_create (surface);
|
cr = cairo_create (surface);
|
||||||
cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
|
cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
gsk_render_node_draw (node, cr);
|
gsk_render_node_draw (node, cr);
|
||||||
|
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
@ -213,6 +302,8 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
|||||||
switch (op->type)
|
switch (op->type)
|
||||||
{
|
{
|
||||||
case GSK_VULKAN_OP_FALLBACK:
|
case GSK_VULKAN_OP_FALLBACK:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||||
gsk_vulkan_render_pass_upload_fallback (self, &op->render, render, uploader);
|
gsk_vulkan_render_pass_upload_fallback (self, &op->render, render, uploader);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -261,6 +352,8 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
|
|||||||
switch (op->type)
|
switch (op->type)
|
||||||
{
|
{
|
||||||
case GSK_VULKAN_OP_FALLBACK:
|
case GSK_VULKAN_OP_FALLBACK:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||||
case GSK_VULKAN_OP_SURFACE:
|
case GSK_VULKAN_OP_SURFACE:
|
||||||
case GSK_VULKAN_OP_TEXTURE:
|
case GSK_VULKAN_OP_TEXTURE:
|
||||||
op->render.vertex_count = gsk_vulkan_blend_pipeline_count_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline));
|
op->render.vertex_count = gsk_vulkan_blend_pipeline_count_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline));
|
||||||
@ -300,6 +393,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
|
|||||||
switch (op->type)
|
switch (op->type)
|
||||||
{
|
{
|
||||||
case GSK_VULKAN_OP_FALLBACK:
|
case GSK_VULKAN_OP_FALLBACK:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||||
case GSK_VULKAN_OP_SURFACE:
|
case GSK_VULKAN_OP_SURFACE:
|
||||||
case GSK_VULKAN_OP_TEXTURE:
|
case GSK_VULKAN_OP_TEXTURE:
|
||||||
{
|
{
|
||||||
@ -348,6 +443,8 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
|
|||||||
switch (op->type)
|
switch (op->type)
|
||||||
{
|
{
|
||||||
case GSK_VULKAN_OP_FALLBACK:
|
case GSK_VULKAN_OP_FALLBACK:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||||
case GSK_VULKAN_OP_SURFACE:
|
case GSK_VULKAN_OP_SURFACE:
|
||||||
case GSK_VULKAN_OP_TEXTURE:
|
case GSK_VULKAN_OP_TEXTURE:
|
||||||
op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source);
|
op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source);
|
||||||
@ -382,6 +479,8 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
|
|||||||
switch (op->type)
|
switch (op->type)
|
||||||
{
|
{
|
||||||
case GSK_VULKAN_OP_FALLBACK:
|
case GSK_VULKAN_OP_FALLBACK:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_CLIP:
|
||||||
|
case GSK_VULKAN_OP_FALLBACK_ROUNDED_CLIP:
|
||||||
case GSK_VULKAN_OP_SURFACE:
|
case GSK_VULKAN_OP_SURFACE:
|
||||||
case GSK_VULKAN_OP_TEXTURE:
|
case GSK_VULKAN_OP_TEXTURE:
|
||||||
if (current_pipeline != op->render.pipeline)
|
if (current_pipeline != op->render.pipeline)
|
||||||
|
@ -17,6 +17,7 @@ void gsk_vulkan_render_pass_free (GskVulk
|
|||||||
void gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
|
void gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
|
||||||
GskVulkanRender *render,
|
GskVulkanRender *render,
|
||||||
const graphene_matrix_t*mvp,
|
const graphene_matrix_t*mvp,
|
||||||
|
const graphene_rect_t *viewport,
|
||||||
GskRenderNode *node);
|
GskRenderNode *node);
|
||||||
|
|
||||||
void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
|
||||||
|
Loading…
Reference in New Issue
Block a user