diff --git a/gsk/gpu/gskgpudownloadop.c b/gsk/gpu/gskgpudownloadop.c index 4aaec9e048..325faaa7db 100644 --- a/gsk/gpu/gskgpudownloadop.c +++ b/gsk/gpu/gskgpudownloadop.c @@ -37,10 +37,8 @@ struct _GskGpuDownloadOp GdkColorState *color_state; gboolean allow_dmabuf; GdkGpuDownloadOpCreateFunc create_func; - GskGpuDownloadFunc func; - gpointer user_data; + GdkTexture **texture; - GdkTexture *texture; GskGpuBuffer *buffer; #ifdef GDK_RENDERING_VULKAN VkSemaphore vk_semaphore; @@ -55,9 +53,6 @@ gsk_gpu_download_op_finish (GskGpuOp *op) if (self->create_func) self->create_func (self); - self->func (self->user_data, self->texture); - - g_object_unref (self->texture); g_object_unref (self->image); g_clear_object (&self->buffer); } @@ -160,8 +155,8 @@ gsk_gpu_download_op_vk_sync_semaphore (GskGpuDownloadOp *self) int fd, sync_file_fd; /* Don't look at where I store my variables plz */ - display = gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (self->texture)); - fd = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (self->texture))->planes[0].fd; + display = gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (*self->texture)); + fd = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (*self->texture))->planes[0].fd; func_vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR) vkGetDeviceProcAddr (display->vk_device, "vkGetSemaphoreFdKHR"); /* vkGetSemaphoreFdKHR implicitly resets the semaphore. @@ -206,7 +201,7 @@ gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self) gdk_memory_texture_builder_set_bytes (builder, bytes); gdk_memory_texture_builder_set_stride (builder, stride); gdk_memory_texture_builder_set_color_state (builder, self->color_state); - self->texture = gdk_memory_texture_builder_build (builder); + *self->texture = gdk_memory_texture_builder_build (builder); g_object_unref (builder); g_bytes_unref (bytes); @@ -219,19 +214,18 @@ gsk_gpu_download_op_vk_command (GskGpuOp *op, GskVulkanCommandState *state) { GskGpuDownloadOp *self = (GskGpuDownloadOp *) op; - gsize width, height, stride; #ifdef HAVE_DMABUF if (self->allow_dmabuf) - self->texture = gsk_vulkan_image_to_dmabuf_texture (GSK_VULKAN_IMAGE (self->image), + *self->texture = gsk_vulkan_image_to_dmabuf_texture (GSK_VULKAN_IMAGE (self->image), self->color_state); - if (self->texture) + if (*self->texture) { GskGpuDevice *device = gsk_gpu_frame_get_device (frame); GskGpuCache *cache = gsk_gpu_device_get_cache (device); VkDevice vk_device = gsk_vulkan_device_get_vk_device (GSK_VULKAN_DEVICE (device)); - gsk_gpu_cache_cache_texture_image (cache, self->texture, self->image, NULL); + gsk_gpu_cache_cache_texture_image (cache, *self->texture, self->image, NULL); if (gsk_vulkan_device_has_feature (GSK_VULKAN_DEVICE (device), GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT)) { @@ -339,11 +333,11 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op, gdk_dmabuf_texture_builder_set_height (db, gsk_gpu_image_get_height (self->image)); gdk_dmabuf_texture_builder_set_color_state (db, self->color_state); - self->texture = gdk_dmabuf_texture_builder_build (db, release_dmabuf_texture, texture, NULL); + *self->texture = gdk_dmabuf_texture_builder_build (db, release_dmabuf_texture, texture, NULL); g_object_unref (db); - if (self->texture) + if (*self->texture) return op->next; gdk_dmabuf_close_fds (&texture->dmabuf); @@ -369,11 +363,11 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op, gdk_gl_texture_builder_set_height (builder, gsk_gpu_image_get_height (self->image)); gdk_gl_texture_builder_set_sync (builder, data->sync); - self->texture = gdk_gl_texture_builder_build (builder, - gsk_gl_texture_data_free, - data); + *self->texture = gdk_gl_texture_builder_build (builder, + gsk_gl_texture_data_free, + data); - gsk_gpu_image_toggle_ref_texture (self->image, self->texture); + gsk_gpu_image_toggle_ref_texture (self->image, *self->texture); gsk_gl_image_steal_texture_ownership (GSK_GL_IMAGE (self->image)); g_object_unref (builder); @@ -396,17 +390,158 @@ void gsk_gpu_download_op (GskGpuFrame *frame, GskGpuImage *image, GdkColorState *color_state, - gboolean allow_dmabuf, - GskGpuDownloadFunc func, - gpointer user_data) + GdkTexture **out_texture) { GskGpuDownloadOp *self; + g_assert (out_texture != NULL && *out_texture == NULL); + self = (GskGpuDownloadOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_DOWNLOAD_OP_CLASS); self->image = g_object_ref (image); self->color_state = gdk_color_state_ref (color_state); - self->allow_dmabuf = allow_dmabuf; - self->func = func, - self->user_data = user_data; + self->texture = out_texture; } + +typedef struct _GskGpuDownloadIntoOp GskGpuDownloadIntoOp; + +typedef void (* GdkGpuDownloadIntoOpCreateFunc) (GskGpuDownloadIntoOp *); + +struct _GskGpuDownloadIntoOp +{ + GskGpuOp op; + + GdkGpuDownloadIntoOpCreateFunc create_func; + GskGpuBuffer *buffer; + + GskGpuImage *image; + GdkColorState *image_color_state; + + GdkMemoryFormat format; + GdkColorState *color_state; + guchar *data; + gsize stride; +}; + +static void +gsk_gpu_download_into_op_finish (GskGpuOp *op) +{ + GskGpuDownloadIntoOp *self = (GskGpuDownloadIntoOp *) op; + + if (self->create_func) + self->create_func (self); + + g_object_unref (self->image); + gdk_color_state_unref (self->image_color_state); + gdk_color_state_unref (self->color_state); + g_clear_object (&self->buffer); +} + +static void +gsk_gpu_download_into_op_print (GskGpuOp *op, + GskGpuFrame *frame, + GString *string, + guint indent) +{ + GskGpuDownloadIntoOp *self = (GskGpuDownloadIntoOp *) op; + + gsk_gpu_print_op (string, indent, "download-into"); + gsk_gpu_print_image (string, self->image); + g_string_append_printf (string, "%s ", gdk_color_state_get_name (self->image_color_state)); + g_string_append_printf (string, "%s ", gdk_memory_format_get_name (self->format)); + g_string_append_printf (string, "%s ", gdk_color_state_get_name (self->color_state)); + gsk_gpu_print_newline (string); +} + +#ifdef GDK_RENDERING_VULKAN +static void +gsk_gpu_download_into_op_vk_create (GskGpuDownloadIntoOp *self) +{ + guchar *data; + GdkMemoryFormat format; + gsize width, height; + + data = gsk_gpu_buffer_map (self->buffer); + format = gsk_gpu_image_get_format (self->image); + width = gsk_gpu_image_get_width (self->image); + height = gsk_gpu_image_get_height (self->image); + + gdk_memory_convert (self->data, + self->stride, + self->format, + self->color_state, + data, + width * gdk_memory_format_bytes_per_pixel (format), + format, + self->image_color_state, + width, + height); +} + +static GskGpuOp * +gsk_gpu_download_into_op_vk_command (GskGpuOp *op, + GskGpuFrame *frame, + GskVulkanCommandState *state) +{ + GskGpuDownloadIntoOp *self = (GskGpuDownloadIntoOp *) op; + + self->buffer = gsk_gpu_download_vk_start (frame, state, self->image); + self->create_func = gsk_gpu_download_into_op_vk_create; + + return op->next; +} +#endif + +static GskGpuOp * +gsk_gpu_download_into_op_gl_command (GskGpuOp *op, + GskGpuFrame *frame, + GskGLCommandState *state) +{ + GskGpuDownloadIntoOp *self = (GskGpuDownloadIntoOp *) op; + + gdk_gl_context_download (GDK_GL_CONTEXT (gsk_gpu_frame_get_context (frame)), + gsk_gl_image_get_texture_id (GSK_GL_IMAGE (self->image)), + gsk_gpu_image_get_format (self->image), + self->image_color_state, + self->data, + self->stride, + self->format, + self->color_state, + gsk_gpu_image_get_width (self->image), + gsk_gpu_image_get_height (self->image)); + + return op->next; +} + +static const GskGpuOpClass GSK_GPU_DOWNLOAD_INTO_OP_CLASS = { + GSK_GPU_OP_SIZE (GskGpuDownloadIntoOp), + GSK_GPU_STAGE_COMMAND, + gsk_gpu_download_into_op_finish, + gsk_gpu_download_into_op_print, +#ifdef GDK_RENDERING_VULKAN + gsk_gpu_download_into_op_vk_command, +#endif + gsk_gpu_download_into_op_gl_command +}; + +void +gsk_gpu_download_into_op (GskGpuFrame *frame, + GskGpuImage *image, + GdkColorState *image_color_state, + GdkMemoryFormat format, + GdkColorState *color_state, + guchar *data, + gsize stride) +{ + GskGpuDownloadIntoOp *self; + + self = (GskGpuDownloadIntoOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_DOWNLOAD_INTO_OP_CLASS); + + self->image = g_object_ref (image); + self->image_color_state = gdk_color_state_ref (image_color_state); + self->format = format; + self->color_state = gdk_color_state_ref (color_state); + self->data = data; + self->stride = stride; +} + diff --git a/gsk/gpu/gskgpudownloadopprivate.h b/gsk/gpu/gskgpudownloadopprivate.h index 6c22a8577d..ebde49636e 100644 --- a/gsk/gpu/gskgpudownloadopprivate.h +++ b/gsk/gpu/gskgpudownloadopprivate.h @@ -4,15 +4,17 @@ G_BEGIN_DECLS -typedef void (* GskGpuDownloadFunc) (gpointer user_data, - GdkTexture *texture); - void gsk_gpu_download_op (GskGpuFrame *frame, GskGpuImage *image, GdkColorState *color_state, - gboolean allow_dmabuf, - GskGpuDownloadFunc func, - gpointer user_data); + GdkTexture **out_texture); +void gsk_gpu_download_into_op (GskGpuFrame *frame, + GskGpuImage *image, + GdkColorState *image_color_state, + GdkMemoryFormat format, + GdkColorState *color_state, + guchar *data, + gsize stride); G_END_DECLS diff --git a/gsk/gpu/gskgpuframe.c b/gsk/gpu/gskgpuframe.c index e782a95683..700267fbc7 100644 --- a/gsk/gpu/gskgpuframe.c +++ b/gsk/gpu/gskgpuframe.c @@ -651,15 +651,6 @@ gsk_gpu_frame_wait (GskGpuFrame *self) gsk_gpu_frame_cleanup (self); } -static void -copy_texture (gpointer user_data, - GdkTexture *texture) -{ - GdkTexture **target = (GdkTexture **) user_data; - - *target = g_object_ref (texture); -} - static void gsk_gpu_frame_record (GskGpuFrame *self, gint64 timestamp, @@ -679,7 +670,7 @@ gsk_gpu_frame_record (GskGpuFrame *self, gsk_gpu_node_processor_process (self, target, target_color_state, clip, node, viewport, pass_type); if (texture) - gsk_gpu_download_op (self, target, target_color_state, TRUE, copy_texture, texture); + gsk_gpu_download_op (self, target, target_color_state, texture); } static void @@ -732,32 +723,6 @@ gsk_gpu_frame_render (GskGpuFrame *self, gsk_gpu_frame_submit (self, pass_type); } -typedef struct _Download Download; - -struct _Download -{ - GdkMemoryFormat format; - GdkColorState *color_state; - guchar *data; - gsize stride; -}; - -static void -do_download (gpointer user_data, - GdkTexture *texture) -{ - Download *download = user_data; - GdkTextureDownloader downloader; - - gdk_texture_downloader_init (&downloader, texture); - gdk_texture_downloader_set_format (&downloader, download->format); - gdk_texture_downloader_set_color_state (&downloader, download->color_state); - gdk_texture_downloader_download_into (&downloader, download->data, download->stride); - gdk_texture_downloader_finish (&downloader); - - g_free (download); -} - void gsk_gpu_frame_download_texture (GskGpuFrame *self, gint64 timestamp, @@ -785,17 +750,13 @@ gsk_gpu_frame_download_texture (GskGpuFrame *self, gsk_gpu_frame_cleanup (self); - gsk_gpu_download_op (self, - image, - gdk_texture_get_color_state (texture), - FALSE, - do_download, - g_memdup2 (&(Download) { - .format = format, - .color_state = color_state, - .data = data, - .stride = stride - }, sizeof (Download))); + gsk_gpu_download_into_op (self, + image, + gdk_texture_get_color_state (texture), + format, + color_state, + data, + stride); gsk_gpu_frame_submit (self, GSK_RENDER_PASS_EXPORT); g_object_unref (image);