onscreen/native: Prevent duplicate damage rectangles in copy path
Since we use the buffer age to create a union of damage rectangles from the last n frames, we often end up with the same rectangle multiple times if an application happens to be changing that is in the same place. This in turn results in duplicate vertices being generated and uploaded to the GPU in the blitting and painting paths. Spend some time (seems to take around 15 microseconds on average on my system) dropping duplicate rectangles using a GHashTable. This partially pays itself back CPU-wise by having to copy fewer rectangles in copy_shared_framebuffer_gpu, looping and calculating less in paint_egl_image. GPU-wise it uploads less data to the GPU and makes the shaders invoke less. (cherry picked from commit 07e021b3a4facec18d1db64deb74b955f55321e9) Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4073> Signed-off-by: Mingi Sung <sungmg@saltyming.net>
This commit is contained in:
parent
47293a748d
commit
cfddb42d22
1 changed files with 28 additions and 5 deletions
|
@ -989,18 +989,41 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||||
if (blit_n_rectangles > 0)
|
if (blit_n_rectangles > 0)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
size_t offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
|
/* Will tend to overallocate a bit if reduction happens below, but doesn't matter much since it's pretty small. */
|
||||||
blit_rectangles = g_newa (MtkRectangle, blit_n_rectangles);
|
blit_rectangles = g_newa (MtkRectangle, blit_n_rectangles);
|
||||||
|
|
||||||
|
GHashTable* hash_table = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
|
|
||||||
for (i = 0; i <= buffer_age; ++i)
|
for (i = 0; i <= buffer_age; ++i)
|
||||||
{
|
{
|
||||||
memcpy (blit_rectangles + offset,
|
int j;
|
||||||
secondary_gpu_state->damage_rectangles[i].rectangles,
|
|
||||||
secondary_gpu_state->damage_rectangles[i].n_rectangles * sizeof(MtkRectangle));
|
|
||||||
|
|
||||||
offset += secondary_gpu_state->damage_rectangles[i].n_rectangles;
|
for (j = 0; j < secondary_gpu_state->damage_rectangles[i].n_rectangles; ++j)
|
||||||
|
{
|
||||||
|
char hash_table_key[100];
|
||||||
|
|
||||||
|
g_snprintf (hash_table_key,
|
||||||
|
100,
|
||||||
|
"%i_%i_%i_%i",
|
||||||
|
secondary_gpu_state->damage_rectangles[i].rectangles[j].x,
|
||||||
|
secondary_gpu_state->damage_rectangles[i].rectangles[j].y,
|
||||||
|
secondary_gpu_state->damage_rectangles[i].rectangles[j].width,
|
||||||
|
secondary_gpu_state->damage_rectangles[i].rectangles[j].height);
|
||||||
|
|
||||||
|
if (g_hash_table_lookup_extended (hash_table, hash_table_key, NULL, NULL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
g_hash_table_insert (hash_table, hash_table_key, NULL);
|
||||||
|
|
||||||
|
memcpy (&blit_rectangles[offset++], &secondary_gpu_state->damage_rectangles[i].rectangles[j], sizeof(MtkRectangle));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_hash_table_destroy (hash_table);
|
||||||
|
|
||||||
|
blit_n_rectangles = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!meta_renderer_native_gles3_blit_shared_bo (egl,
|
if (!meta_renderer_native_gles3_blit_shared_bo (egl,
|
||||||
|
|
Loading…
Reference in a new issue