mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-16 15:14:17 +00:00
Merge branch 'ngl-coloring-underlines' into 'master'
Optimize underlines in text See merge request GNOME/gtk!3414
This commit is contained in:
commit
715449695c
@ -116,20 +116,25 @@ populate_emoji_text (void)
|
||||
GtkWidget *textview;
|
||||
GtkTextBuffer *buffer;
|
||||
GString *s;
|
||||
GtkTextIter iter;
|
||||
|
||||
s = g_string_sized_new (1000 * 30 * 4);
|
||||
s = g_string_sized_new (500 * 30 * 4);
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
if (i % 2)
|
||||
g_string_append (s, "x");
|
||||
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
|
||||
for (int j = 0; j < 30; j++)
|
||||
g_string_append (s, "💓x");
|
||||
{
|
||||
g_string_append (s, "💓");
|
||||
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
|
||||
}
|
||||
g_string_append (s, "\n");
|
||||
}
|
||||
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_set_text (buffer, s->str, s->len);
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
gtk_text_buffer_insert_markup (buffer, &iter, s->str, s->len);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
|
||||
|
@ -169,7 +169,7 @@ gsk_ngl_command_queue_print_batch (GskNglCommandQueue *self,
|
||||
for (guint i = 0; i < batch->draw.bind_count; i++)
|
||||
{
|
||||
const GskNglCommandBind *bind = &self->batch_binds.items[batch->draw.bind_offset + i];
|
||||
g_print (" Bind[%d]: %u\n", bind->texture, bind->id);
|
||||
g_printerr (" Bind[%d]: %u\n", bind->texture, bind->id);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < batch->draw.uniform_count; i++)
|
||||
@ -951,6 +951,7 @@ gsk_ngl_command_queue_execute (GskNglCommandQueue *self,
|
||||
guint n_binds = 0;
|
||||
guint n_fbos = 0;
|
||||
guint n_uniforms = 0;
|
||||
guint n_programs = 0;
|
||||
guint vao_id;
|
||||
guint vbo_id;
|
||||
int textures[4];
|
||||
@ -1062,6 +1063,8 @@ gsk_ngl_command_queue_execute (GskNglCommandQueue *self,
|
||||
{
|
||||
program = batch->any.program;
|
||||
glUseProgram (program);
|
||||
|
||||
n_programs++;
|
||||
}
|
||||
|
||||
if (apply_framebuffer (&framebuffer, batch->draw.framebuffer))
|
||||
@ -1144,6 +1147,7 @@ gsk_ngl_command_queue_execute (GskNglCommandQueue *self,
|
||||
gdk_profiler_set_int_counter (self->metrics.n_binds, n_binds);
|
||||
gdk_profiler_set_int_counter (self->metrics.n_uniforms, n_uniforms);
|
||||
gdk_profiler_set_int_counter (self->metrics.n_fbos, n_fbos);
|
||||
gdk_profiler_set_int_counter (self->metrics.n_programs, n_programs);
|
||||
gdk_profiler_set_int_counter (self->metrics.n_uploads, self->n_uploads);
|
||||
gdk_profiler_set_int_counter (self->metrics.queue_depth, self->batches.len);
|
||||
|
||||
@ -1415,6 +1419,7 @@ gsk_ngl_command_queue_set_profiler (GskNglCommandQueue *self,
|
||||
self->metrics.n_fbos = gdk_profiler_define_int_counter ("fbos", "Number of framebuffers attached");
|
||||
self->metrics.n_uniforms = gdk_profiler_define_int_counter ("uniforms", "Number of uniforms changed");
|
||||
self->metrics.n_uploads = gdk_profiler_define_int_counter ("uploads", "Number of texture uploads");
|
||||
self->metrics.n_programs = gdk_profiler_define_int_counter ("programs", "Number of program changes");
|
||||
self->metrics.queue_depth = gdk_profiler_define_int_counter ("gl-queue-depth", "Depth of GL command batches");
|
||||
}
|
||||
#endif
|
||||
|
@ -250,6 +250,7 @@ struct _GskNglCommandQueue
|
||||
guint n_fbos;
|
||||
guint n_uniforms;
|
||||
guint n_uploads;
|
||||
guint n_programs;
|
||||
guint queue_depth;
|
||||
} metrics;
|
||||
|
||||
|
@ -1360,16 +1360,54 @@ blur_node (GskNglRenderJob *job,
|
||||
*max_y = job->offset_y + node->bounds.origin.y + node->bounds.size.height + half_blur_extra;
|
||||
}
|
||||
|
||||
#define ATLAS_SIZE 512
|
||||
|
||||
static inline void
|
||||
gsk_ngl_render_job_visit_color_node (GskNglRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
{
|
||||
guint16 color[4];
|
||||
GskNglProgram *program;
|
||||
GskNglCommandBatch *batch;
|
||||
|
||||
rgba_to_half (gsk_color_node_get_color (node), color);
|
||||
gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, color));
|
||||
gsk_ngl_render_job_draw_rect_with_color (job, &node->bounds, color);
|
||||
gsk_ngl_render_job_end_draw (job);
|
||||
|
||||
/* Avoid switching away from the coloring program for
|
||||
* rendering a solid color.
|
||||
*/
|
||||
program = CHOOSE_PROGRAM (job, coloring);
|
||||
batch = gsk_ngl_command_queue_get_batch (job->command_queue);
|
||||
|
||||
if (batch->any.kind == GSK_NGL_COMMAND_KIND_DRAW &&
|
||||
batch->any.program == program->id)
|
||||
{
|
||||
GskNglRenderOffscreen offscreen = {0};
|
||||
|
||||
gsk_ngl_render_job_begin_draw (job, program);
|
||||
|
||||
/* The top left few pixels in our atlases are always
|
||||
* solid white, so we can use it here, without
|
||||
* having to choose any particular atlas texture.
|
||||
*/
|
||||
offscreen.was_offscreen = FALSE;
|
||||
offscreen.area.x = 1.f / ATLAS_SIZE;
|
||||
offscreen.area.y = 1.f / ATLAS_SIZE;
|
||||
offscreen.area.x2 = 2.f / ATLAS_SIZE;
|
||||
offscreen.area.y2 = 2.f / ATLAS_SIZE;
|
||||
|
||||
gsk_ngl_render_job_draw_offscreen_with_color (job,
|
||||
&node->bounds,
|
||||
&offscreen,
|
||||
color);
|
||||
|
||||
gsk_ngl_render_job_end_draw (job);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, color));
|
||||
gsk_ngl_render_job_draw_rect_with_color (job, &node->bounds, color);
|
||||
gsk_ngl_render_job_end_draw (job);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gsk/gskdebugprivate.h>
|
||||
|
||||
#include "gsknglcommandqueueprivate.h"
|
||||
@ -239,6 +240,51 @@ gsk_ngl_texture_atlas_pack (GskNglTextureAtlas *self,
|
||||
return rect.was_packed;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_ngl_texture_atlas_initialize (GskNglDriver *driver,
|
||||
GskNglTextureAtlas *atlas)
|
||||
{
|
||||
/* Insert a single pixel at 0,0 for use in coloring */
|
||||
|
||||
gboolean packed;
|
||||
int x, y;
|
||||
guint gl_format;
|
||||
guint gl_type;
|
||||
guint8 pixel_data[4 * 3 * 3];
|
||||
|
||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||
"Initializing Atlas");
|
||||
|
||||
packed = gsk_ngl_texture_atlas_pack (atlas, 3, 3, &x, &y);
|
||||
g_assert (packed);
|
||||
g_assert (x == 0 && y == 0);
|
||||
|
||||
memset (pixel_data, 255, sizeof pixel_data);
|
||||
|
||||
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
|
||||
{
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_format = GL_BGRA;
|
||||
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
}
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
|
||||
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
0, 0,
|
||||
3, 3,
|
||||
gl_format, gl_type,
|
||||
pixel_data);
|
||||
|
||||
gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
|
||||
|
||||
driver->command_queue->n_uploads++;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_ngl_texture_atlases_pack (GskNglDriver *driver,
|
||||
int width,
|
||||
@ -265,6 +311,8 @@ gsk_ngl_texture_atlases_pack (GskNglDriver *driver,
|
||||
/* No atlas has enough space, so create a new one... */
|
||||
atlas = gsk_ngl_driver_create_atlas (driver);
|
||||
|
||||
gsk_ngl_texture_atlas_initialize (driver, atlas);
|
||||
|
||||
/* Pack it onto that one, which surely has enough space... */
|
||||
if (!gsk_ngl_texture_atlas_pack (atlas, width, height, &x, &y))
|
||||
g_assert_not_reached ();
|
||||
|
Loading…
Reference in New Issue
Block a user