diff options
author | Benjamin Otte <otte@redhat.com> | 2016-12-24 06:16:54 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2016-12-24 06:19:16 +0100 |
commit | aa0ec774bf7d4b63641b1cdc887103cb7da65f55 (patch) | |
tree | d4605111551a7f04b15494463093f8900f12436a | |
parent | 81c487b8415fed4990b069b03245b2aa11f12ab7 (diff) | |
download | gtk+-aa0ec774bf7d4b63641b1cdc887103cb7da65f55.tar.gz |
vulkan: Add proof-of-concept clip implementation
We can now clip to cicular rounded rectangles when drawing colors.
-rw-r--r-- | gsk/gskvulkanrender.c | 3 | ||||
-rw-r--r-- | gsk/gskvulkanrenderpass.c | 9 | ||||
-rw-r--r-- | gsk/gskvulkanrenderprivate.h | 1 | ||||
-rw-r--r-- | gsk/resources/vulkan/color-clip-rounded.frag.glsl | 51 | ||||
-rw-r--r-- | gsk/resources/vulkan/color-clip-rounded.frag.spv | bin | 0 -> 5228 bytes | |||
-rw-r--r-- | gsk/resources/vulkan/color-clip-rounded.vert.glsl | 36 | ||||
-rw-r--r-- | gsk/resources/vulkan/color-clip-rounded.vert.spv | bin | 0 -> 2176 bytes |
7 files changed, 97 insertions, 3 deletions
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c index e2e8167b4c..d23ff8cd3e 100644 --- a/gsk/gskvulkanrender.c +++ b/gsk/gskvulkanrender.c @@ -314,7 +314,8 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self, GskVulkanPipeline * (* create_func) (GskVulkanPipelineLayout *layout, const char *name, VkRenderPass render_pass); } pipeline_info[GSK_VULKAN_N_PIPELINES] = { { "blit", gsk_vulkan_blend_pipeline_new }, - { "color", gsk_vulkan_color_pipeline_new } + { "color", gsk_vulkan_color_pipeline_new }, + { "color-clip-rounded", gsk_vulkan_color_pipeline_new } }; g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL); diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index dc26f31f1c..21a5cb9c88 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -98,6 +98,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self, .type = GSK_VULKAN_OP_FALLBACK, .render.node = node }; + GskVulkanPipelineType pipeline_type; switch (gsk_render_node_get_node_type (node)) { @@ -126,10 +127,14 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self, return; case GSK_COLOR_NODE: - if (!gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds)) + if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds)) + pipeline_type = GSK_VULKAN_PIPELINE_COLOR; + else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR) + pipeline_type = GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED; + else FALLBACK ("Color nodes can't deal with clip type %u\n", constants->clip.type); 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, pipeline_type); g_array_append_val (self->render_ops, op); return; diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h index e44f2639f2..c5f7379daf 100644 --- a/gsk/gskvulkanrenderprivate.h +++ b/gsk/gskvulkanrenderprivate.h @@ -12,6 +12,7 @@ G_BEGIN_DECLS typedef enum { GSK_VULKAN_PIPELINE_BLIT, GSK_VULKAN_PIPELINE_COLOR, + GSK_VULKAN_PIPELINE_COLOR_CLIP_ROUNDED, /* add more */ GSK_VULKAN_N_PIPELINES } GskVulkanPipelineType; diff --git a/gsk/resources/vulkan/color-clip-rounded.frag.glsl b/gsk/resources/vulkan/color-clip-rounded.frag.glsl new file mode 100644 index 0000000000..9825f7858d --- /dev/null +++ b/gsk/resources/vulkan/color-clip-rounded.frag.glsl @@ -0,0 +1,51 @@ +#version 420 core + +layout(location = 0) in vec2 inPos; +layout(location = 1) in vec4 inColor; +layout(location = 2) in vec4 inClipBounds; +layout(location = 3) in vec4 inClipWidths; + +layout(location = 0) out vec4 color; + +struct RoundedRect { + vec4 bounds; + vec4 corners; +}; + +float clip(vec2 pos, RoundedRect r) { + vec2 ref_tl = r.bounds.xy + vec2( r.corners.x, r.corners.x); + vec2 ref_tr = r.bounds.zy + vec2(-r.corners.y, r.corners.y); + vec2 ref_br = r.bounds.zw + vec2(-r.corners.z, -r.corners.z); + vec2 ref_bl = r.bounds.xw + vec2( r.corners.w, -r.corners.w); + + float d_tl = distance(pos, ref_tl); + float d_tr = distance(pos, ref_tr); + float d_br = distance(pos, ref_br); + float d_bl = distance(pos, ref_bl); + + float pixels_per_fragment = length(fwidth(pos.xy)); + float nudge = 0.5 * pixels_per_fragment; + vec4 distances = vec4(d_tl, d_tr, d_br, d_bl) - r.corners + nudge; + + bvec4 is_out = bvec4(pos.x < ref_tl.x && pos.y < ref_tl.y, + pos.x > ref_tr.x && pos.y < ref_tr.y, + pos.x > ref_br.x && pos.y > ref_br.y, + pos.x < ref_bl.x && pos.y > ref_bl.y); + + float distance_from_border = dot(vec4(is_out), + max(vec4(0.0, 0.0, 0.0, 0.0), distances)); + + // Move the distance back into pixels. + distance_from_border /= pixels_per_fragment; + // Apply a more gradual fade out to transparent. + //distance_from_border -= 0.5; + + return 1.0 - smoothstep(0.0, 1.0, distance_from_border); +} + +void main() +{ + RoundedRect r = RoundedRect(vec4(inClipBounds.xy, inClipBounds.xy + inClipBounds.zw), inClipWidths); + + color = vec4(inColor.rgb * inColor.a, inColor.a) * clip (inPos, r); +} diff --git a/gsk/resources/vulkan/color-clip-rounded.frag.spv b/gsk/resources/vulkan/color-clip-rounded.frag.spv Binary files differnew file mode 100644 index 0000000000..cf650af95c --- /dev/null +++ b/gsk/resources/vulkan/color-clip-rounded.frag.spv diff --git a/gsk/resources/vulkan/color-clip-rounded.vert.glsl b/gsk/resources/vulkan/color-clip-rounded.vert.glsl new file mode 100644 index 0000000000..a3c55351a2 --- /dev/null +++ b/gsk/resources/vulkan/color-clip-rounded.vert.glsl @@ -0,0 +1,36 @@ +#version 420 core + +layout(location = 0) in vec4 inRect; +layout(location = 1) in vec4 inColor; + +layout(push_constant) uniform PushConstants { + mat4 mvp; + vec4 clip_bounds; + vec4 clip_widths; + vec4 clip_heights; +} push; + +layout(location = 0) out vec2 outPos; +layout(location = 1) out flat vec4 outColor; +layout(location = 2) out flat vec4 outClipBounds; +layout(location = 3) out flat vec4 outClipWidths; + +out gl_PerVertex { + vec4 gl_Position; +}; + +vec2 offsets[6] = { vec2(0.0, 0.0), + vec2(1.0, 0.0), + vec2(0.0, 1.0), + vec2(0.0, 1.0), + vec2(1.0, 0.0), + vec2(1.0, 1.0) }; + +void main() { + vec2 pos = inRect.xy + inRect.zw * offsets[gl_VertexIndex]; + gl_Position = push.mvp * vec4 (pos, 0.0, 1.0); + outPos = pos; + outColor = inColor; + outClipBounds = push.clip_bounds; + outClipWidths = push.clip_widths; +} diff --git a/gsk/resources/vulkan/color-clip-rounded.vert.spv b/gsk/resources/vulkan/color-clip-rounded.vert.spv Binary files differnew file mode 100644 index 0000000000..4414e997dd --- /dev/null +++ b/gsk/resources/vulkan/color-clip-rounded.vert.spv |