diff options
author | Matthias Clasen <mclasen@redhat.com> | 2018-01-06 09:36:55 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2018-01-06 09:36:55 -0500 |
commit | 3771c95c72d591d3ed6ecf143fa85e1fea0a3d11 (patch) | |
tree | fb66e92aee87e28bee3c363a84f7874f763b7bda /gsk/vulkan/gskvulkanclip.c | |
parent | 3c38ebb906319cb75688f9929b65ecf2a4fd3440 (diff) | |
download | gtk+-3771c95c72d591d3ed6ecf143fa85e1fea0a3d11.tar.gz |
gsk: Move Vulkan sources to a subdirectory
Following what was already done for GL.
Diffstat (limited to 'gsk/vulkan/gskvulkanclip.c')
-rw-r--r-- | gsk/vulkan/gskvulkanclip.c | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/gsk/vulkan/gskvulkanclip.c b/gsk/vulkan/gskvulkanclip.c new file mode 100644 index 0000000000..d927d88f13 --- /dev/null +++ b/gsk/vulkan/gskvulkanclip.c @@ -0,0 +1,187 @@ +#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; + } + + default: + g_assert_not_reached (); + 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; + + default: + g_assert_not_reached (); + return FALSE; + } + + return TRUE; +} + +gboolean +gsk_vulkan_clip_transform (GskVulkanClip *dest, + const GskVulkanClip *src, + const graphene_matrix_t *transform, + const graphene_rect_t *viewport) +{ + switch (src->type) + { + default: + g_assert_not_reached(); + return FALSE; + + case GSK_VULKAN_CLIP_ALL_CLIPPED: + gsk_vulkan_clip_init_copy (dest, src); + return TRUE; + + case GSK_VULKAN_CLIP_NONE: + gsk_vulkan_clip_init_empty (dest, viewport); + return TRUE; + + case GSK_VULKAN_CLIP_RECT: + case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR: + case GSK_VULKAN_CLIP_ROUNDED: + /* FIXME: Handle 2D operations, in particular transform and scale */ + return FALSE; + } +} + +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); + } +} |