gpu: Actually ensure a downloadable dmabuf
For some formats, we could not download the dmabuf directly - in particular YUV formats. For those, do a copy on the GPU into the correct format. While we're at it, also check the desired format and colorstate and if they don't match, do the conversion on the GPU instead of using gdk_memory_convert(). Reserve the CPU conversion for situations where the GPU doesn't support the final format - like for example G8A8 (or often also RGB16).
This commit is contained in:
@@ -761,6 +761,27 @@ gsk_gpu_frame_download_texture (GskGpuFrame *self,
|
||||
|
||||
gsk_gpu_frame_cleanup (self);
|
||||
|
||||
if (gsk_gpu_image_get_format (image) != format ||
|
||||
image_cs != color_state)
|
||||
{
|
||||
GskGpuImage *converted;
|
||||
|
||||
converted = gsk_gpu_node_processor_convert_image (self,
|
||||
format,
|
||||
color_state,
|
||||
image,
|
||||
image_cs);
|
||||
if (converted == NULL)
|
||||
{
|
||||
g_critical ("Conversion into readable format failed");
|
||||
g_object_unref (image);
|
||||
return;
|
||||
}
|
||||
g_object_unref (image);
|
||||
image = converted;
|
||||
image_cs = color_state;
|
||||
}
|
||||
|
||||
gsk_gpu_download_into_op (self,
|
||||
image,
|
||||
image_cs,
|
||||
|
||||
@@ -4404,3 +4404,82 @@ gsk_gpu_node_processor_process (GskGpuFrame *frame,
|
||||
cairo_region_destroy (clip);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_node_processor_convert_image (GskGpuFrame *frame,
|
||||
GdkMemoryFormat target_format,
|
||||
GdkColorState *target_color_state,
|
||||
GskGpuImage *image,
|
||||
GdkColorState *image_color_state)
|
||||
{
|
||||
GskGpuNodeProcessor self;
|
||||
GskGpuImage *converted, *intermediate = NULL;
|
||||
gsize width, height;
|
||||
|
||||
width = gsk_gpu_image_get_width (image);
|
||||
height = gsk_gpu_image_get_height (image);
|
||||
|
||||
converted = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
|
||||
FALSE,
|
||||
target_format,
|
||||
gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_SRGB,
|
||||
width,
|
||||
height);
|
||||
if (converted == NULL)
|
||||
return NULL;
|
||||
|
||||
/* We need to go via an intermediate colorstate */
|
||||
if (!GDK_IS_DEFAULT_COLOR_STATE (image_color_state) &&
|
||||
!GDK_IS_DEFAULT_COLOR_STATE (target_color_state))
|
||||
{
|
||||
GdkColorState *ccs = gdk_color_state_get_rendering_color_state (image_color_state);
|
||||
|
||||
intermediate = gsk_gpu_copy_image (frame, ccs, image, image_color_state, FALSE);
|
||||
if (intermediate == NULL)
|
||||
return NULL;
|
||||
image = intermediate;
|
||||
image_color_state = ccs;
|
||||
}
|
||||
|
||||
gsk_gpu_node_processor_init (&self,
|
||||
frame,
|
||||
converted,
|
||||
target_color_state,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gsk_gpu_render_pass_begin_op (frame,
|
||||
converted,
|
||||
&(cairo_rectangle_int_t) { 0, 0, width, height },
|
||||
GSK_GPU_LOAD_OP_DONT_CARE,
|
||||
NULL,
|
||||
GSK_RENDER_PASS_OFFSCREEN);
|
||||
|
||||
gsk_gpu_node_processor_sync_globals (&self, 0);
|
||||
|
||||
if (GDK_IS_DEFAULT_COLOR_STATE (target_color_state))
|
||||
{
|
||||
gsk_gpu_node_processor_image_op (&self,
|
||||
image,
|
||||
image_color_state,
|
||||
GSK_GPU_SAMPLER_DEFAULT,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gpu_node_processor_convert_to (&self,
|
||||
image,
|
||||
image_color_state,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
}
|
||||
|
||||
gsk_gpu_render_pass_end_op (self.frame,
|
||||
converted,
|
||||
GSK_RENDER_PASS_OFFSCREEN);
|
||||
gsk_gpu_node_processor_finish (&self);
|
||||
|
||||
g_clear_object (&intermediate);
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,5 +12,10 @@ void gsk_gpu_node_processor_process (GskGpuF
|
||||
GskRenderNode *node,
|
||||
const graphene_rect_t *viewport,
|
||||
GskRenderPassType pass_type);
|
||||
GskGpuImage * gsk_gpu_node_processor_convert_image (GskGpuFrame *frame,
|
||||
GdkMemoryFormat target_format,
|
||||
GdkColorState *target_color_state,
|
||||
GskGpuImage *image,
|
||||
GdkColorState *image_color_state);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
Reference in New Issue
Block a user