Compare commits
3 Commits
scrollable
...
wip/otte/d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f8e1133e4 | ||
|
|
25bebb6e73 | ||
|
|
c39a551fee |
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -543,6 +543,7 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
const char *legacy = "";
|
||||
const char *gl3 = "";
|
||||
const char *gles = "";
|
||||
const char *dither = "";
|
||||
int program_id;
|
||||
int vertex_id;
|
||||
int fragment_id;
|
||||
@@ -572,11 +573,14 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
if (self->gl3)
|
||||
gl3 = "#define GSK_GL3 1\n";
|
||||
|
||||
if (GSK_DEBUG_CHECK (NO_DITHER))
|
||||
dither = "#define GSK_NO_DITHER 1\n";
|
||||
|
||||
vertex_id = glCreateShader (GL_VERTEX_SHADER);
|
||||
glShaderSource (vertex_id,
|
||||
10,
|
||||
11,
|
||||
(const char *[]) {
|
||||
version, debug, legacy, gl3, gles,
|
||||
version, debug, legacy, gl3, gles, dither,
|
||||
clip,
|
||||
get_shader_string (self->all_preamble),
|
||||
get_shader_string (self->vertex_preamble),
|
||||
@@ -589,6 +593,7 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
strlen (legacy),
|
||||
strlen (gl3),
|
||||
strlen (gles),
|
||||
strlen (dither),
|
||||
strlen (clip),
|
||||
g_bytes_get_size (self->all_preamble),
|
||||
g_bytes_get_size (self->vertex_preamble),
|
||||
@@ -607,9 +612,9 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
|
||||
fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
|
||||
glShaderSource (fragment_id,
|
||||
10,
|
||||
11,
|
||||
(const char *[]) {
|
||||
version, debug, legacy, gl3, gles,
|
||||
version, debug, legacy, gl3, gles, dither,
|
||||
clip,
|
||||
get_shader_string (self->all_preamble),
|
||||
get_shader_string (self->fragment_preamble),
|
||||
@@ -622,6 +627,7 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
strlen (legacy),
|
||||
strlen (gl3),
|
||||
strlen (gles),
|
||||
strlen (dither),
|
||||
strlen (clip),
|
||||
g_bytes_get_size (self->all_preamble),
|
||||
g_bytes_get_size (self->fragment_preamble),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,30 @@ vec2 gsk_get_frag_coord() {
|
||||
return fc;
|
||||
}
|
||||
|
||||
void gskSetOutputColor(vec4 color) {
|
||||
vec4 result;
|
||||
// hash12() from https://www.shadertoy.com/view/4djSRW
|
||||
float gsk_interleaved_gradient_noise (vec2 p)
|
||||
{
|
||||
vec3 p3 = fract(vec3(p.xyx) * .1031);
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return fract((p3.x + p3.y) * p3.z);
|
||||
}
|
||||
|
||||
#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;
|
||||
vec4 gskDither(vec4 color) {
|
||||
#if defined(GSK_NO_DITHER)
|
||||
return color;
|
||||
#else
|
||||
float coverage = gsk_rounded_rect_coverage(gsk_create_rect(u_clip_rect),
|
||||
gsk_get_frag_coord());
|
||||
result = color * coverage;
|
||||
#endif
|
||||
if (u_bit_depth > 10)
|
||||
return color;
|
||||
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
gl_FragColor = result;
|
||||
#else
|
||||
outputColor = result;
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
|
||||
void gskSetScaledOutputColor(vec4 color, float alpha) {
|
||||
vec4 gsk_get_output_color(vec4 color, float alpha) {
|
||||
vec4 result;
|
||||
|
||||
#if defined(NO_CLIP)
|
||||
@@ -154,9 +156,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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ static const GdkDebugKey gsk_debug_keys[] = {
|
||||
{ "surface", GSK_DEBUG_SURFACE, "Information about surfaces" },
|
||||
{ "fallback", GSK_DEBUG_FALLBACK, "Information about fallbacks" },
|
||||
{ "glyphcache", GSK_DEBUG_GLYPH_CACHE, "Information about glyph caching" },
|
||||
{ "no-dither", GSK_DEBUG_NO_DITHER, "Disable dithering" },
|
||||
{ "geometry", GSK_DEBUG_GEOMETRY, "Show borders (when using cairo)" },
|
||||
{ "full-redraw", GSK_DEBUG_FULL_REDRAW, "Force full redraws" },
|
||||
{ "sync", GSK_DEBUG_SYNC, "Sync after each frame" },
|
||||
|
||||
@@ -15,11 +15,12 @@ typedef enum {
|
||||
GSK_DEBUG_FALLBACK = 1 << 6,
|
||||
GSK_DEBUG_GLYPH_CACHE = 1 << 7,
|
||||
/* flags below may affect behavior */
|
||||
GSK_DEBUG_GEOMETRY = 1 << 9,
|
||||
GSK_DEBUG_FULL_REDRAW = 1 << 10,
|
||||
GSK_DEBUG_SYNC = 1 << 11,
|
||||
GSK_DEBUG_VULKAN_STAGING_IMAGE = 1 << 12,
|
||||
GSK_DEBUG_VULKAN_STAGING_BUFFER = 1 << 13
|
||||
GSK_DEBUG_NO_DITHER = 1 << 9,
|
||||
GSK_DEBUG_GEOMETRY = 1 << 10,
|
||||
GSK_DEBUG_FULL_REDRAW = 1 << 11,
|
||||
GSK_DEBUG_SYNC = 1 << 12,
|
||||
GSK_DEBUG_VULKAN_STAGING_IMAGE = 1 << 13,
|
||||
GSK_DEBUG_VULKAN_STAGING_BUFFER = 1 << 14
|
||||
} GskDebugFlags;
|
||||
|
||||
#define GSK_DEBUG_ANY ((1 << 13) - 1)
|
||||
|
||||
Reference in New Issue
Block a user