summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Wick <sebastian.wick@redhat.com>2022-05-03 15:22:49 +0200
committerBenjamin Otte <otte@redhat.com>2022-05-28 04:57:38 +0200
commitc39a551fee3a14b88cce7d2d5c4e57578dd45bd2 (patch)
treed841e637ecff0f25e3c7b931c9051fdcb3071413
parent38ec040fce4a9ca41fba59d1ccb66a9065345951 (diff)
downloadgtk+-c39a551fee3a14b88cce7d2d5c4e57578dd45bd2.tar.gz
gsk/gl: Apply dither to gradients and shadows
-rw-r--r--gsk/gl/gskglcommandqueue.c16
-rw-r--r--gsk/gl/gskglcommandqueueprivate.h3
-rw-r--r--gsk/gl/gskgldriver.c7
-rw-r--r--gsk/gl/gskgldriverprivate.h2
-rw-r--r--gsk/gl/gskglrenderjob.c103
-rw-r--r--gsk/gl/resources/conic_gradient.glsl2
-rw-r--r--gsk/gl/resources/linear_gradient.glsl6
-rw-r--r--gsk/gl/resources/outset_shadow.glsl2
-rw-r--r--gsk/gl/resources/preamble.fs.glsl65
-rw-r--r--gsk/gl/resources/radial_gradient.glsl2
10 files changed, 153 insertions, 55 deletions
diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c
index 4d7ef4b3d3..ed70fb1aad 100644
--- a/gsk/gl/gskglcommandqueue.c
+++ b/gsk/gl/gskglcommandqueue.c
@@ -1246,10 +1246,13 @@ gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
int min_filter,
int mag_filter,
guint *out_fbo_id,
- guint *out_texture_id)
+ guint *out_texture_id,
+ int *out_bit_depth)
{
+ GdkGLContext *context = self->context;
GLuint fbo_id = 0;
GLint texture_id;
+ int bit_depth;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
g_assert (width > 0);
@@ -1266,6 +1269,7 @@ gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
{
*out_fbo_id = 0;
*out_texture_id = 0;
+ *out_bit_depth = 0;
return FALSE;
}
@@ -1275,8 +1279,18 @@ gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
g_assert_cmphex (glCheckFramebufferStatus (GL_FRAMEBUFFER), ==, GL_FRAMEBUFFER_COMPLETE);
+ bit_depth = 8;
+ if (context && gdk_gl_context_check_version (context, 0, 0, 3, 0))
+ {
+ glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
+ &bit_depth);
+ }
+
*out_fbo_id = fbo_id;
*out_texture_id = texture_id;
+ *out_bit_depth = bit_depth;
return TRUE;
}
diff --git a/gsk/gl/gskglcommandqueueprivate.h b/gsk/gl/gskglcommandqueueprivate.h
index 48911305a8..a3985370ee 100644
--- a/gsk/gl/gskglcommandqueueprivate.h
+++ b/gsk/gl/gskglcommandqueueprivate.h
@@ -298,7 +298,8 @@ gboolean gsk_gl_command_queue_create_render_target (GskGLCommandQueue
int min_filter,
int mag_filter,
guint *out_fbo_id,
- guint *out_texture_id);
+ guint *out_texture_id,
+ int *out_bit_depth);
void gsk_gl_command_queue_delete_program (GskGLCommandQueue *self,
guint program_id);
void gsk_gl_command_queue_clear (GskGLCommandQueue *self,
diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c
index 179e870d80..7bda780159 100644
--- a/gsk/gl/gskgldriver.c
+++ b/gsk/gl/gskgldriver.c
@@ -387,6 +387,7 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
gsk_gl_program_add_uniform (program, "u_viewport", UNIFORM_SHARED_VIEWPORT); \
gsk_gl_program_add_uniform (program, "u_projection", UNIFORM_SHARED_PROJECTION); \
gsk_gl_program_add_uniform (program, "u_modelview", UNIFORM_SHARED_MODELVIEW); \
+ gsk_gl_program_add_uniform (program, "u_bit_depth", UNIFORM_SHARED_BIT_DEPTH); \
\
uniforms \
\
@@ -899,6 +900,7 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
{
guint framebuffer_id;
guint texture_id;
+ int bit_depth;
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), FALSE);
g_return_val_if_fail (GSK_IS_GL_COMMAND_QUEUE (self->command_queue), FALSE);
@@ -927,7 +929,8 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
width, height,
format,
min_filter, mag_filter,
- &framebuffer_id, &texture_id))
+ &framebuffer_id, &texture_id,
+ &bit_depth))
{
GskGLRenderTarget *render_target;
@@ -939,6 +942,7 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
render_target->height = height;
render_target->framebuffer_id = framebuffer_id;
render_target->texture_id = texture_id;
+ render_target->bit_depth = bit_depth;
*out_render_target = render_target;
@@ -1098,6 +1102,7 @@ gsk_gl_driver_lookup_shader (GskGLDriver *self,
gsk_gl_program_add_uniform (program, "u_viewport", UNIFORM_SHARED_VIEWPORT);
gsk_gl_program_add_uniform (program, "u_projection", UNIFORM_SHARED_PROJECTION);
gsk_gl_program_add_uniform (program, "u_modelview", UNIFORM_SHARED_MODELVIEW);
+ gsk_gl_program_add_uniform (program, "u_bit_depth", UNIFORM_SHARED_BIT_DEPTH);
have_alpha = gsk_gl_program_add_uniform (program, "u_alpha", UNIFORM_SHARED_ALPHA);
gsk_gl_program_add_uniform (program, "u_size", UNIFORM_CUSTOM_SIZE);
diff --git a/gsk/gl/gskgldriverprivate.h b/gsk/gl/gskgldriverprivate.h
index accae5b3bb..1cb439da1a 100644
--- a/gsk/gl/gskgldriverprivate.h
+++ b/gsk/gl/gskgldriverprivate.h
@@ -35,6 +35,7 @@ enum {
UNIFORM_SHARED_VIEWPORT,
UNIFORM_SHARED_PROJECTION,
UNIFORM_SHARED_MODELVIEW,
+ UNIFORM_SHARED_BIT_DEPTH,
UNIFORM_SHARED_LAST
};
@@ -91,6 +92,7 @@ struct _GskGLRenderTarget
int format;
int width;
int height;
+ int bit_depth;
};
struct _GskGLDriver
diff --git a/gsk/gl/gskglrenderjob.c b/gsk/gl/gskglrenderjob.c
index 97b3d9d4c9..3d59b2340e 100644
--- a/gsk/gl/gskglrenderjob.c
+++ b/gsk/gl/gskglrenderjob.c
@@ -173,6 +173,10 @@ struct _GskGLRenderJob
* looking at the format of the framebuffer we are rendering on.
*/
int target_format;
+
+ /* Bit depth of the framebuffer we render into
+ */
+ int bit_depth;
};
typedef struct _GskGLRenderOffscreen
@@ -209,6 +213,39 @@ static gboolean gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob
const GskRenderNode *node,
GskGLRenderOffscreen *offscreen);
+static int
+get_framebuffer_bit_depth (GdkGLContext *context,
+ guint framebuffer)
+{
+ int size;
+
+ if (!gdk_gl_context_check_version (context, 0, 0, 3, 0))
+ return 8;
+
+ glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
+ glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER,
+ framebuffer ? GL_COLOR_ATTACHMENT0
+ : gdk_gl_context_get_use_es (context) ? GL_BACK
+ : GL_BACK_LEFT,
+ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &size);
+
+ return size;
+}
+
+static int
+get_framebuffer_format (GdkGLContext *context,
+ guint framebuffer)
+{
+ int size = get_framebuffer_bit_depth (context, framebuffer);
+
+ if (size > 16)
+ return GL_RGBA32F;
+ else if (size > 8)
+ return GL_RGBA16F;
+ else
+ return GL_RGBA8;
+}
+
static inline int
get_target_format (GskGLRenderJob *job,
const GskRenderNode *node)
@@ -475,6 +512,21 @@ init_projection_matrix (graphene_matrix_t *projection,
graphene_matrix_scale (projection, 1, -1, 1);
}
+static inline int
+gsk_gl_render_job_set_bit_depth (GskGLRenderJob *job,
+ int bit_depth)
+{
+ if (job->bit_depth != bit_depth)
+ {
+ int ret = job->bit_depth;
+ job->bit_depth = bit_depth;
+ job->driver->stamps[UNIFORM_SHARED_BIT_DEPTH]++;
+ return ret;
+ }
+
+ return bit_depth;
+}
+
static inline float
gsk_gl_render_job_set_alpha (GskGLRenderJob *job,
float alpha)
@@ -1157,6 +1209,12 @@ gsk_gl_render_job_begin_draw (GskGLRenderJob *job,
UNIFORM_SHARED_ALPHA,
job->driver->stamps[UNIFORM_SHARED_ALPHA],
job->alpha);
+
+ gsk_gl_uniform_state_set1f (program->uniforms,
+ program->program_info,
+ UNIFORM_SHARED_BIT_DEPTH,
+ job->driver->stamps[UNIFORM_SHARED_BIT_DEPTH],
+ job->bit_depth);
}
#define CHOOSE_PROGRAM(job,name) \
@@ -1312,6 +1370,7 @@ blur_offscreen (GskGLRenderJob *job,
graphene_matrix_t prev_projection;
graphene_rect_t prev_viewport;
guint prev_fbo;
+ int prev_bit_depth;
g_assert (blur_radius_x > 0);
g_assert (blur_radius_y > 0);
@@ -1346,6 +1405,7 @@ blur_offscreen (GskGLRenderJob *job,
/* Bind new framebuffer and clear it */
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, pass1->framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
+ prev_bit_depth = gsk_gl_render_job_set_bit_depth (job, pass1->bit_depth);
/* Begin drawing the first horizontal pass, using offscreen as the
* source texture for the program.
@@ -1375,6 +1435,7 @@ blur_offscreen (GskGLRenderJob *job,
/* Bind second pass framebuffer and clear it */
gsk_gl_command_queue_bind_framebuffer (job->command_queue, pass2->framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
+ gsk_gl_render_job_set_bit_depth (job, pass2->bit_depth);
/* Draw using blur program with first pass as source texture */
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blur));
@@ -1404,6 +1465,7 @@ blur_offscreen (GskGLRenderJob *job,
gsk_gl_render_job_set_viewport (job, &prev_viewport, NULL);
gsk_gl_render_job_set_projection (job, &prev_projection);
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
+ gsk_gl_render_job_set_bit_depth (job, prev_bit_depth);
gsk_gl_driver_release_render_target (job->driver, pass1, TRUE);
@@ -2223,6 +2285,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
graphene_matrix_t prev_projection;
graphene_rect_t prev_viewport;
guint prev_fbo;
+ int prev_bit_depth;
/* TODO: In the following code, we have to be careful about where we apply the scale.
* We're manually scaling stuff (e.g. the outline) so we can later use texture_width
@@ -2265,6 +2328,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
+ prev_bit_depth = gsk_gl_render_job_set_bit_depth (job, render_target->bit_depth);
gsk_gl_render_job_transform_rounded_rect (job, &outline_to_blur, &transformed_outline);
@@ -2291,6 +2355,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
gsk_gl_render_job_set_projection (job, &prev_projection);
gsk_gl_render_job_set_viewport (job, &prev_viewport, NULL);
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
+ gsk_gl_render_job_set_bit_depth (job, prev_bit_depth);
offscreen.texture_id = render_target->texture_id;
init_full_texture_region (&offscreen);
@@ -2523,6 +2588,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
graphene_matrix_t prev_projection;
graphene_rect_t prev_viewport;
guint prev_fbo;
+ int prev_bit_depth;
gsk_gl_driver_create_render_target (job->driver,
texture_width, texture_height,
@@ -2553,6 +2619,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
/* Bind render target and clear it */
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
+ prev_bit_depth = gsk_gl_render_job_set_bit_depth (job, render_target->bit_depth);
/* Draw the outline using color program */
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, color));
@@ -2582,6 +2649,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
blurred_texture_id);
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
+ gsk_gl_render_job_set_bit_depth (job, prev_bit_depth);
}
else
{
@@ -3924,6 +3992,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
graphene_rect_t prev_viewport;
float prev_alpha;
guint prev_fbo;
+ int prev_bit_depth;
if (!gsk_gl_driver_create_render_target (job->driver,
texture_width, texture_height,
@@ -3954,6 +4023,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
+ prev_bit_depth = gsk_gl_render_job_set_bit_depth (job, render_target->bit_depth);
if (offscreen->reset_clip)
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (job->viewport));
@@ -3973,6 +4043,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
gsk_gl_render_job_set_projection (job, &prev_projection);
gsk_gl_render_job_set_alpha (job, prev_alpha);
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
+ gsk_gl_render_job_set_bit_depth (job, prev_bit_depth);
job->offset_x = offset_x;
job->offset_y = offset_y;
@@ -3996,6 +4067,8 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
guint framebuffer_id;
guint texture_id;
guint surface_height;
+ int bit_depth;
+ int prev_bit_depth;
g_return_if_fail (job != NULL);
g_return_if_fail (root != NULL);
@@ -4017,12 +4090,14 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
MAX (1, job->viewport.size.height),
job->target_format,
GL_NEAREST, GL_NEAREST,
- &framebuffer_id, &texture_id))
+ &framebuffer_id, &texture_id,
+ &bit_depth))
return;
/* Setup drawing to our offscreen texture/framebuffer which is flipped */
gsk_gl_command_queue_bind_framebuffer (job->command_queue, framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
+ prev_bit_depth = gsk_gl_render_job_set_bit_depth (job, bit_depth);
/* Visit all nodes creating batches */
gdk_gl_context_push_debug_group (job->command_queue->context, "Building command queue");
@@ -4033,6 +4108,7 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
gsk_gl_render_job_set_alpha (job, 1.0f);
gsk_gl_command_queue_bind_framebuffer (job->command_queue, job->framebuffer);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
+ gsk_gl_render_job_set_bit_depth (job, prev_bit_depth);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -4107,30 +4183,6 @@ gsk_gl_render_job_set_debug_fallback (GskGLRenderJob *job,
job->debug_fallback = !!debug_fallback;
}
-static int
-get_framebuffer_format (GdkGLContext *context,
- guint framebuffer)
-{
- int size;
-
- if (!gdk_gl_context_check_version (context, 0, 0, 3, 0))
- return GL_RGBA8;
-
- glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
- glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER,
- framebuffer ? GL_COLOR_ATTACHMENT0
- : gdk_gl_context_get_use_es (context) ? GL_BACK
- : GL_BACK_LEFT,
- GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, &size);
-
- if (size > 16)
- return GL_RGBA32F;
- else if (size > 8)
- return GL_RGBA16F;
- else
- return GL_RGBA8;
-}
-
GskGLRenderJob *
gsk_gl_render_job_new (GskGLDriver *driver,
const graphene_rect_t *viewport,
@@ -4177,6 +4229,7 @@ gsk_gl_render_job_new (GskGLDriver *driver,
gsk_gl_render_job_set_alpha (job, 1.0f);
gsk_gl_render_job_set_projection_from_rect (job, viewport, NULL);
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, scale_factor, scale_factor));
+ gsk_gl_render_job_set_bit_depth (job, get_framebuffer_bit_depth (job->command_queue->context, framebuffer));
/* Setup our initial clip. If region is NULL then we are drawing the
* whole viewport. Otherwise, we need to convert the region to a
diff --git a/gsk/gl/resources/conic_gradient.glsl b/gsk/gl/resources/conic_gradient.glsl
index f1d33cd6a7..422a9b4563 100644
--- a/gsk/gl/resources/conic_gradient.glsl
+++ b/gsk/gl/resources/conic_gradient.glsl
@@ -78,7 +78,7 @@ void main() {
vec4 curr_color = gsk_premultiply(get_color(i));
vec4 next_color = gsk_premultiply(get_color(i + 1));
vec4 color = mix(curr_color, next_color, f);
- gskSetScaledOutputColor(color, u_alpha);
+ gskSetScaledDitheredOutputColor(color, u_alpha);
return;
}
}
diff --git a/gsk/gl/resources/linear_gradient.glsl b/gsk/gl/resources/linear_gradient.glsl
index fa130be4cb..5ff81c75fb 100644
--- a/gsk/gl/resources/linear_gradient.glsl
+++ b/gsk/gl/resources/linear_gradient.glsl
@@ -87,7 +87,8 @@ void main() {
}
if (offset >= get_offset(u_num_color_stops - 1)) {
- gskSetOutputColor(gsk_scaled_premultiply(get_color(u_num_color_stops - 1), u_alpha));
+ vec4 color = get_color(u_num_color_stops - 1);
+ gskSetDitheredOutputColor(gsk_scaled_premultiply(color, u_alpha));
return;
}
@@ -99,8 +100,7 @@ void main() {
float f = (offset - curr_offset) / (next_offset - curr_offset);
vec4 curr_color = gsk_premultiply(get_color(i));
vec4 next_color = gsk_premultiply(get_color(i + 1));
- vec4 color = mix(curr_color, next_color, f);
- gskSetScaledOutputColor(color, u_alpha);
+ gskSetScaledDitheredOutputColor(mix(curr_color, next_color, f), u_alpha);
return;
}
}
diff --git a/gsk/gl/resources/outset_shadow.glsl b/gsk/gl/resources/outset_shadow.glsl
index 44b05aa152..2a262cf066 100644
--- a/gsk/gl/resources/outset_shadow.glsl
+++ b/gsk/gl/resources/outset_shadow.glsl
@@ -30,5 +30,5 @@ void main() {
alpha *= (1.0 - clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outline), frag), 0.0, 1.0));
- gskSetScaledOutputColor(final_color, alpha);
+ gskSetScaledDitheredOutputColor(final_color, alpha);
}
diff --git a/gsk/gl/resources/preamble.fs.glsl b/gsk/gl/resources/preamble.fs.glsl
index c1c5a954ee..534311f4db 100644
--- a/gsk/gl/resources/preamble.fs.glsl
+++ b/gsk/gl/resources/preamble.fs.glsl
@@ -4,6 +4,7 @@ uniform mat4 u_modelview;
uniform float u_alpha;
uniform vec4 u_viewport;
uniform vec4[3] u_clip_rect;
+uniform float u_bit_depth;
#if defined(GSK_LEGACY)
_OUT_ vec4 outputColor;
@@ -117,29 +118,25 @@ vec2 gsk_get_frag_coord() {
return fc;
}
-void gskSetOutputColor(vec4 color) {
- vec4 result;
+// from "NEXT GENERATION POST PROCESSING IN CALL OF DUTY: ADVANCED WARFARE"
+// http://advances.realtimerendering.com/s2014/index.html
+float gsk_interleaved_gradient_noise(vec2 uv) {
+ const vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189);
+ return fract(magic.z * fract(dot(uv, magic.xy)));
+}
-#if defined(NO_CLIP)
- result = color;
-#elif defined(RECT_CLIP)
- float coverage = gsk_rect_coverage(gsk_get_bounds(u_clip_rect),
- gsk_get_frag_coord());
- result = color * coverage;
-#else
- float coverage = gsk_rounded_rect_coverage(gsk_create_rect(u_clip_rect),
- gsk_get_frag_coord());
- result = color * coverage;
-#endif
+vec4 gskDither(vec4 color) {
+ if (u_bit_depth > 10)
+ return color;
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
- gl_FragColor = result;
-#else
- outputColor = result;
-#endif
+ float noise = gsk_interleaved_gradient_noise(gsk_get_frag_coord()) - 0.5;
+ // scale the noise to the number of steps we have
+ noise = noise / (pow(2.0, u_bit_depth) - 1.0);
+ color = vec4(color.rgb + noise, color.a);
+ return color;
}
-void gskSetScaledOutputColor(vec4 color, float alpha) {
+vec4 gsk_get_output_color(vec4 color, float alpha) {
vec4 result;
#if defined(NO_CLIP)
@@ -154,9 +151,35 @@ void gskSetScaledOutputColor(vec4 color, float alpha) {
result = color * (alpha * coverage);
#endif
+ return result;
+}
+
+void gsk_set_output_color(vec4 color) {
#if defined(GSK_GLES) || defined(GSK_LEGACY)
- gl_FragColor = result;
+ gl_FragColor = color;
#else
- outputColor = result;
+ outputColor = color;
#endif
}
+
+void gskSetOutputColor(vec4 color) {
+ vec4 result = gsk_get_output_color(color, 1.0);
+ gsk_set_output_color(result);
+}
+
+void gskSetDitheredOutputColor(vec4 color) {
+ vec4 result = gsk_get_output_color(color, 1.0);
+ result = gskDither(result);
+ gsk_set_output_color(result);
+}
+
+void gskSetScaledOutputColor(vec4 color, float alpha) {
+ vec4 result = gsk_get_output_color(color, alpha);
+ gsk_set_output_color(result);
+}
+
+void gskSetScaledDitheredOutputColor(vec4 color, float alpha) {
+ vec4 result = gsk_get_output_color(color, alpha);
+ result = gskDither(result);
+ gsk_set_output_color(result);
+}
diff --git a/gsk/gl/resources/radial_gradient.glsl b/gsk/gl/resources/radial_gradient.glsl
index 59fad00290..82c5600769 100644
--- a/gsk/gl/resources/radial_gradient.glsl
+++ b/gsk/gl/resources/radial_gradient.glsl
@@ -80,7 +80,7 @@ void main() {
vec4 curr_color = gsk_premultiply(get_color(i));
vec4 next_color = gsk_premultiply(get_color(i + 1));
vec4 color = mix(curr_color, next_color, f);
- gskSetScaledOutputColor(color, u_alpha);
+ gskSetScaledDitheredOutputColor(color, u_alpha);
return;
}
}