mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
gpu: Add supersampling for gradients
Unless GSK_GPU_SKIP=gradients is given, we sample every point 4x instead of 1x. That makes the shader run slower (by roughly a factor of 2.5x) but it improves quality quite a bit.
This commit is contained in:
parent
6e4a526ddf
commit
48c1f5fd27
@ -8,6 +8,8 @@
|
||||
|
||||
#include "gpu/shaders/gskgpuconicgradientinstance.h"
|
||||
|
||||
#define VARIATION_SUPERSAMPLING (1 << 0)
|
||||
|
||||
typedef struct _GskGpuConicGradientOp GskGpuConicGradientOp;
|
||||
|
||||
struct _GskGpuConicGradientOp
|
||||
@ -67,7 +69,7 @@ gsk_gpu_conic_gradient_op (GskGpuFrame *frame,
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_CONIC_GRADIENT_OP_CLASS,
|
||||
0,
|
||||
(gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GRADIENTS) ? VARIATION_SUPERSAMPLING : 0),
|
||||
clip,
|
||||
NULL,
|
||||
&instance);
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
#include "gpu/shaders/gskgpulineargradientinstance.h"
|
||||
|
||||
#define VARIATION_REPEATING 1
|
||||
#define VARIATION_SUPERSAMPLING (1 << 0)
|
||||
#define VARIATION_REPEATING (1 << 1)
|
||||
|
||||
typedef struct _GskGpuLinearGradientOp GskGpuLinearGradientOp;
|
||||
|
||||
@ -73,7 +74,8 @@ gsk_gpu_linear_gradient_op (GskGpuFrame *frame,
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_LINEAR_GRADIENT_OP_CLASS,
|
||||
repeating ? VARIATION_REPEATING : 0,
|
||||
(repeating ? VARIATION_REPEATING : 0) |
|
||||
(gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GRADIENTS) ? VARIATION_SUPERSAMPLING : 0),
|
||||
clip,
|
||||
NULL,
|
||||
&instance);
|
||||
|
@ -3149,30 +3149,11 @@ gsk_gpu_node_processor_repeat_tile (GskGpuNodeProcessor *self,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Take advantage of caching machinery if we can.
|
||||
* If the sizes don't match, we can't though, because we need to
|
||||
* create the right sized image for tiling.
|
||||
*/
|
||||
if (gsk_rect_equal (&child->bounds, &clipped_child_bounds))
|
||||
{
|
||||
graphene_rect_t tex_rect;
|
||||
image = gsk_gpu_node_processor_get_node_as_image (self,
|
||||
0,
|
||||
GSK_GPU_IMAGE_STRAIGHT_ALPHA,
|
||||
&clipped_child_bounds,
|
||||
child,
|
||||
&tex_rect);
|
||||
/* The math went wrong */
|
||||
g_warn_if_fail (gsk_rect_equal (&tex_rect, &clipped_child_bounds));
|
||||
}
|
||||
else
|
||||
{
|
||||
GSK_DEBUG (FALLBACK, "Offscreening node '%s' for tiling", g_type_name_from_instance ((GTypeInstance *) child));
|
||||
image = gsk_gpu_render_pass_op_offscreen (self->frame,
|
||||
&self->scale,
|
||||
&clipped_child_bounds,
|
||||
child);
|
||||
}
|
||||
GSK_DEBUG (FALLBACK, "Offscreening node '%s' for tiling", g_type_name_from_instance ((GTypeInstance *) child));
|
||||
image = gsk_gpu_render_pass_op_offscreen (self->frame,
|
||||
&self->scale,
|
||||
&clipped_child_bounds,
|
||||
child);
|
||||
|
||||
g_return_if_fail (image);
|
||||
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
#include "gpu/shaders/gskgpuradialgradientinstance.h"
|
||||
|
||||
#define VARIATION_REPEATING 1
|
||||
#define VARIATION_SUPERSAMPLING (1 << 0)
|
||||
#define VARIATION_REPEATING (1 << 1)
|
||||
|
||||
typedef struct _GskGpuRadialGradientOp GskGpuRadialGradientOp;
|
||||
|
||||
@ -75,7 +76,8 @@ gsk_gpu_radial_gradient_op (GskGpuFrame *frame,
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_RADIAL_GRADIENT_OP_CLASS,
|
||||
repeating ? VARIATION_REPEATING : 0,
|
||||
(repeating ? VARIATION_REPEATING : 0) |
|
||||
(gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_GRADIENTS) ? VARIATION_SUPERSAMPLING : 0),
|
||||
clip,
|
||||
NULL,
|
||||
&instance);
|
||||
|
@ -27,6 +27,7 @@ static const GdkDebugKey gsk_gpu_optimization_keys[] = {
|
||||
{ "uber", GSK_GPU_OPTIMIZE_UBER, "Don't use the uber shader" },
|
||||
{ "clear", GSK_GPU_OPTIMIZE_CLEAR, "Use shaders instead of vkCmdClearAttachment()/glClear()" },
|
||||
{ "merge", GSK_GPU_OPTIMIZE_MERGE, "Use one vkCmdDraw()/glDrawArrays() per operation" },
|
||||
{ "gradients", GSK_GPU_OPTIMIZE_GRADIENTS, "Don't supersample gradients" },
|
||||
|
||||
{ "gl-baseinstance", GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE, "Assume no ARB/EXT_base_instance support" },
|
||||
};
|
||||
|
@ -114,7 +114,8 @@ typedef enum {
|
||||
GSK_GPU_OPTIMIZE_UBER = 1 << 0,
|
||||
GSK_GPU_OPTIMIZE_CLEAR = 1 << 1,
|
||||
GSK_GPU_OPTIMIZE_MERGE = 1 << 2,
|
||||
GSK_GPU_OPTIMIZE_GRADIENTS = 1 << 3,
|
||||
/* These require hardware support */
|
||||
GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE = 1 << 3,
|
||||
GSK_GPU_OPTIMIZE_GL_BASE_INSTANCE = 1 << 4,
|
||||
} GskGpuOptimizations;
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "common.glsl"
|
||||
|
||||
#define VARIATION_SUPERSAMPLING ((GSK_VARIATION & (1u << 0)) == (1u << 0))
|
||||
|
||||
PASS(0) vec2 _pos;
|
||||
PASS_FLAT(1) Rect _rect;
|
||||
PASS_FLAT(2) vec4 _color0;
|
||||
@ -117,8 +119,19 @@ run (out vec4 color,
|
||||
{
|
||||
float alpha = rect_coverage (_rect, _pos);
|
||||
|
||||
vec2 conic_pos = _pos / GSK_GLOBAL_SCALE - _center;
|
||||
color = alpha * get_gradient_color_at (conic_pos);
|
||||
vec2 pos = _pos / GSK_GLOBAL_SCALE - _center;
|
||||
if (VARIATION_SUPERSAMPLING)
|
||||
{
|
||||
vec2 dpos = 0.25 * fwidth (pos);
|
||||
color = alpha * 0.25 * (get_gradient_color_at (pos + vec2(- dpos.x, - dpos.y)) +
|
||||
get_gradient_color_at (pos + vec2(- dpos.x, dpos.y)) +
|
||||
get_gradient_color_at (pos + vec2( dpos.x, - dpos.y)) +
|
||||
get_gradient_color_at (pos + vec2( dpos.x, dpos.y)));
|
||||
}
|
||||
else
|
||||
{
|
||||
color = alpha * get_gradient_color_at (pos);
|
||||
}
|
||||
position = _pos;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "common.glsl"
|
||||
|
||||
#define VARIATION_REPEATING ((GSK_VARIATION & 1u) == 1u)
|
||||
#define VARIATION_SUPERSAMPLING ((GSK_VARIATION & (1u << 0)) == (1u << 0))
|
||||
#define VARIATION_REPEATING ((GSK_VARIATION & (1u << 1)) == (1u << 1))
|
||||
|
||||
PASS(0) vec2 _pos;
|
||||
PASS_FLAT(1) Rect _rect;
|
||||
@ -104,18 +105,37 @@ get_gradient_color (float offset)
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4
|
||||
get_gradient_color_at (float offset)
|
||||
{
|
||||
if (VARIATION_REPEATING)
|
||||
offset = fract (offset);
|
||||
else
|
||||
offset = clamp (offset, 0.0, 1.0);
|
||||
|
||||
return color_premultiply (get_gradient_color (offset));
|
||||
}
|
||||
|
||||
void
|
||||
run (out vec4 color,
|
||||
out vec2 position)
|
||||
{
|
||||
float alpha = rect_coverage (_rect, _pos);
|
||||
float offset;
|
||||
if (VARIATION_REPEATING)
|
||||
offset = fract (_offset);
|
||||
else
|
||||
offset = clamp (_offset, 0.0, 1.0);
|
||||
|
||||
color = alpha * color_premultiply (get_gradient_color (offset));
|
||||
if (VARIATION_SUPERSAMPLING)
|
||||
{
|
||||
float dx = 0.25 * dFdx (_offset);
|
||||
float dy = 0.25 * dFdy (_offset);
|
||||
color = alpha * 0.25 * (get_gradient_color_at (_offset - dx - dy) +
|
||||
get_gradient_color_at (_offset - dx + dy) +
|
||||
get_gradient_color_at (_offset + dx - dy) +
|
||||
get_gradient_color_at (_offset + dx + dy));
|
||||
}
|
||||
else
|
||||
{
|
||||
color = alpha * get_gradient_color_at (_offset);
|
||||
}
|
||||
|
||||
position = _pos;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "common.glsl"
|
||||
|
||||
#define VARIATION_REPEATING ((GSK_VARIATION & 1u) == 1u)
|
||||
#define VARIATION_SUPERSAMPLING ((GSK_VARIATION & (1u << 0)) == (1u << 0))
|
||||
#define VARIATION_REPEATING ((GSK_VARIATION & (1u << 1)) == (1u << 1))
|
||||
|
||||
PASS(0) vec2 _pos;
|
||||
PASS_FLAT(1) Rect _rect;
|
||||
@ -123,7 +124,20 @@ run (out vec4 color,
|
||||
{
|
||||
float alpha = rect_coverage (_rect, _pos);
|
||||
|
||||
color = alpha * get_gradient_color_at (_pos / GSK_GLOBAL_SCALE - _center_radius.xy);
|
||||
vec2 pos = _pos / GSK_GLOBAL_SCALE - _center_radius.xy;
|
||||
if (VARIATION_SUPERSAMPLING)
|
||||
{
|
||||
vec2 dpos = 0.25 * fwidth (pos);
|
||||
color = alpha * 0.25 * (get_gradient_color_at (pos + vec2(- dpos.x, - dpos.y)) +
|
||||
get_gradient_color_at (pos + vec2(- dpos.x, dpos.y)) +
|
||||
get_gradient_color_at (pos + vec2( dpos.x, - dpos.y)) +
|
||||
get_gradient_color_at (pos + vec2( dpos.x, dpos.y)));
|
||||
}
|
||||
else
|
||||
{
|
||||
color = alpha * get_gradient_color_at (pos);
|
||||
}
|
||||
|
||||
position = _pos;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user