gpu: Handle nested buffer writes

when doing get_node_as_image(), that may spawn a new buffer writer that
writes into the samme buffer when rendering an offscreen with patterns.

So as a more or less hacky workaround, we now abort the current buffer
write and restart it once we've created the image.
This commit is contained in:
Benjamin Otte 2023-09-07 22:11:24 +02:00
parent 28f4666366
commit 16c804c5e3
4 changed files with 24 additions and 1 deletions

View File

@ -33,6 +33,14 @@ gsk_gpu_buffer_writer_rewind (GskGpuBufferWriter *self,
self->size = size;
}
guchar *
gsk_gpu_buffer_writer_backup (GskGpuBufferWriter *self,
gsize *out_size)
{
*out_size = self->size - self->initial_size;
return g_memdup (self->data + self->initial_size, *out_size);
}
void
gsk_gpu_buffer_writer_ensure_size (GskGpuBufferWriter *self,
gsize size)

View File

@ -18,6 +18,7 @@ struct _GskGpuBufferWriter
gboolean commit);
guchar *data;
gsize initial_size;
gsize size;
gsize allocated;
};
@ -28,6 +29,8 @@ void gsk_gpu_buffer_writer_abort (GskGpuB
gsize gsk_gpu_buffer_writer_get_size (GskGpuBufferWriter *self);
void gsk_gpu_buffer_writer_rewind (GskGpuBufferWriter *self,
gsize size);
guchar * gsk_gpu_buffer_writer_backup (GskGpuBufferWriter *self,
gsize *out_size);
void gsk_gpu_buffer_writer_ensure_size (GskGpuBufferWriter *self,
gsize size);
void gsk_gpu_buffer_writer_append (GskGpuBufferWriter *self,

View File

@ -16,7 +16,7 @@
#define DEFAULT_VERTEX_BUFFER_SIZE 128 * 1024
/* GL_MAX_UNIFORM_BLOCK_SIZE is at least this size */
/* GL_MAX_UNIFORM_BLOCK_SIZE is at 16384 */
#define DEFAULT_STORAGE_BUFFER_SIZE 16 * 1024
#define GDK_ARRAY_NAME gsk_gpu_ops
@ -446,6 +446,7 @@ gsk_gpu_frame_write_buffer_memory (GskGpuFrame *self,
writer->finish = gsk_gpu_frame_buffer_memory_finish;
writer->data = priv->storage_buffer_data;
writer->initial_size = priv->storage_buffer_used;
writer->size = priv->storage_buffer_used;
writer->allocated = gsk_gpu_buffer_get_size (priv->storage_buffer);
}

View File

@ -1198,6 +1198,8 @@ gsk_gpu_node_processor_create_node_pattern (GskGpuNodeProcessor *self,
{
GskRenderNodeType node_type;
graphene_rect_t bounds;
guchar *tmp_data;
gsize tmp_size;
node_type = gsk_render_node_get_node_type (node);
if (node_type >= G_N_ELEMENTS (nodes_vtable))
@ -1219,6 +1221,9 @@ gsk_gpu_node_processor_create_node_pattern (GskGpuNodeProcessor *self,
if (n_images == 0)
return FALSE;
tmp_data = gsk_gpu_buffer_writer_backup (writer, &tmp_size);
gsk_gpu_buffer_writer_abort (writer);
images[0].image = gsk_gpu_node_procesor_get_node_as_image (self, node, &bounds);
images[0].sampler = GSK_GPU_SAMPLER_DEFAULT;
images[0].descriptor = gsk_gpu_frame_get_image_descriptor (self->frame,
@ -1226,6 +1231,12 @@ gsk_gpu_node_processor_create_node_pattern (GskGpuNodeProcessor *self,
images[0].sampler);
*out_n_images = 1;
gsk_gpu_frame_write_buffer_memory (self->frame, writer);
if (tmp_size)
{
gsk_gpu_buffer_writer_append (writer, sizeof (float), tmp_data, tmp_size);
g_free (tmp_data);
}
gsk_gpu_buffer_writer_append_uint (writer, GSK_GPU_PATTERN_TEXTURE);
gsk_gpu_buffer_writer_append_uint (writer, images[0].descriptor);
gsk_gpu_buffer_writer_append_rect (writer, &bounds, &self->offset);