gpu: create SRGB images
If desired, try creating GL_SRGB images. Pass a try_srgb boolean down to the image creation functions and have them attempt to create images like that. When it is not possible to create srgb images in the given format, just fall back to regular images. The calling code is meant to check the GSK_GPU_IMAGE_SRGB flags to determine the actual format of the resulting image.
This commit is contained in:
@@ -76,6 +76,7 @@ gsk_gl_device_create_offscreen_image (GskGpuDevice *device,
|
||||
|
||||
return gsk_gl_image_new (self,
|
||||
gdk_memory_depth_get_format (depth),
|
||||
gdk_memory_depth_is_srgb (depth),
|
||||
GSK_GPU_IMAGE_RENDERABLE | GSK_GPU_IMAGE_FILTERABLE,
|
||||
width,
|
||||
height);
|
||||
@@ -85,6 +86,7 @@ static GskGpuImage *
|
||||
gsk_gl_device_create_upload_image (GskGpuDevice *device,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
@@ -92,6 +94,7 @@ gsk_gl_device_create_upload_image (GskGpuDevice *device,
|
||||
|
||||
return gsk_gl_image_new (self,
|
||||
format,
|
||||
try_srgb,
|
||||
0,
|
||||
width,
|
||||
height);
|
||||
@@ -107,6 +110,7 @@ gsk_gl_device_create_download_image (GskGpuDevice *device,
|
||||
|
||||
return gsk_gl_image_new (self,
|
||||
gdk_memory_depth_get_format (depth),
|
||||
gdk_memory_depth_is_srgb (depth),
|
||||
GSK_GPU_IMAGE_RENDERABLE,
|
||||
width,
|
||||
height);
|
||||
@@ -121,6 +125,7 @@ gsk_gl_device_create_atlas_image (GskGpuDevice *device,
|
||||
|
||||
return gsk_gl_image_new (self,
|
||||
GDK_MEMORY_DEFAULT,
|
||||
FALSE,
|
||||
GSK_GPU_IMAGE_RENDERABLE,
|
||||
width,
|
||||
height);
|
||||
|
||||
@@ -125,6 +125,7 @@ gsk_gl_image_new_backbuffer (GskGLDevice *device,
|
||||
GskGpuImage *
|
||||
gsk_gl_image_new (GskGLDevice *device,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
GskGpuImageFlags required_flags,
|
||||
gsize width,
|
||||
gsize height)
|
||||
@@ -152,7 +153,15 @@ gsk_gl_image_new (GskGLDevice *device,
|
||||
&self->gl_type,
|
||||
swizzle);
|
||||
|
||||
self->gl_internal_format = gl_internal_format;
|
||||
if (try_srgb && gl_internal_srgb_format != -1)
|
||||
{
|
||||
self->gl_internal_format = gl_internal_srgb_format;
|
||||
flags |= GSK_GPU_IMAGE_SRGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->gl_internal_format = gl_internal_format;
|
||||
}
|
||||
|
||||
gsk_gpu_image_setup (GSK_GPU_IMAGE (self),
|
||||
flags,
|
||||
|
||||
@@ -18,6 +18,7 @@ GskGpuImage * gsk_gl_image_new_backbuffer (GskGLDe
|
||||
gsize height);
|
||||
GskGpuImage * gsk_gl_image_new (GskGLDevice *device,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
GskGpuImageFlags required_flags,
|
||||
gsize width,
|
||||
gsize height);
|
||||
|
||||
@@ -829,7 +829,7 @@ gsk_gpu_cache_lookup_glyph_image (GskGpuCache *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
image = gsk_gpu_device_create_upload_image (self->device, GDK_MEMORY_DEFAULT, FALSE, rect.size.width, rect.size.height),
|
||||
image = gsk_gpu_device_create_upload_image (self->device, FALSE, GDK_MEMORY_DEFAULT, FALSE, rect.size.width, rect.size.height),
|
||||
rect.origin.x = 0;
|
||||
rect.origin.y = 0;
|
||||
padding = 0;
|
||||
|
||||
@@ -230,10 +230,11 @@ GskGpuImage *
|
||||
gsk_gpu_device_create_upload_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_upload_image (self, with_mipmap, format, width, height);
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_upload_image (self, with_mipmap, format, try_srgb, width, height);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
|
||||
@@ -35,6 +35,7 @@ struct _GskGpuDeviceClass
|
||||
GskGpuImage * (* create_upload_image) (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height);
|
||||
GskGpuImage * (* create_download_image) (GskGpuDevice *self,
|
||||
@@ -67,6 +68,7 @@ GskGpuImage * gsk_gpu_device_create_atlas_image (GskGpuD
|
||||
GskGpuImage * gsk_gpu_device_create_upload_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height);
|
||||
GskGpuImage * gsk_gpu_device_create_download_image (GskGpuDevice *self,
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "gskvulkanimageprivate.h"
|
||||
#endif
|
||||
|
||||
#include "gdk/gdkcolorstateprivate.h"
|
||||
#include "gdk/gdkglcontextprivate.h"
|
||||
#include "gsk/gskdebugprivate.h"
|
||||
|
||||
@@ -304,6 +305,7 @@ gsk_gpu_upload_texture_op_try (GskGpuFrame *frame,
|
||||
image = gsk_gpu_device_create_upload_image (gsk_gpu_frame_get_device (frame),
|
||||
with_mipmap,
|
||||
gdk_texture_get_format (texture),
|
||||
gdk_color_state_get_no_srgb_tf (gdk_texture_get_color_state (texture)) != NULL,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture));
|
||||
if (image == NULL)
|
||||
@@ -470,6 +472,7 @@ gsk_gpu_upload_cairo_op (GskGpuFrame *frame,
|
||||
self->image = gsk_gpu_device_create_upload_image (gsk_gpu_frame_get_device (frame),
|
||||
FALSE,
|
||||
GDK_MEMORY_DEFAULT,
|
||||
gdk_color_state_get_no_srgb_tf (GDK_COLOR_STATE_SRGB) != NULL,
|
||||
ceil (graphene_vec2_get_x (scale) * viewport->size.width),
|
||||
ceil (graphene_vec2_get_y (scale) * viewport->size.height));
|
||||
self->viewport = *viewport;
|
||||
|
||||
@@ -371,6 +371,7 @@ gsk_vulkan_device_create_offscreen_image (GskGpuDevice *device,
|
||||
return gsk_vulkan_image_new_for_offscreen (self,
|
||||
with_mipmap,
|
||||
gdk_memory_depth_get_format (depth),
|
||||
gdk_memory_depth_is_srgb (depth),
|
||||
width,
|
||||
height);
|
||||
}
|
||||
@@ -391,6 +392,7 @@ static GskGpuImage *
|
||||
gsk_vulkan_device_create_upload_image (GskGpuDevice *device,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
@@ -399,6 +401,7 @@ gsk_vulkan_device_create_upload_image (GskGpuDevice *device,
|
||||
return gsk_vulkan_image_new_for_upload (self,
|
||||
with_mipmap,
|
||||
format,
|
||||
try_srgb,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
@@ -415,6 +418,7 @@ gsk_vulkan_device_create_download_image (GskGpuDevice *device,
|
||||
#ifdef HAVE_DMABUF
|
||||
image = gsk_vulkan_image_new_dmabuf (self,
|
||||
gdk_memory_depth_get_format (depth),
|
||||
gdk_memory_depth_is_srgb (depth),
|
||||
width,
|
||||
height);
|
||||
if (image != NULL)
|
||||
@@ -424,6 +428,7 @@ gsk_vulkan_device_create_download_image (GskGpuDevice *device,
|
||||
image = gsk_vulkan_image_new_for_offscreen (self,
|
||||
FALSE,
|
||||
gdk_memory_depth_get_format (depth),
|
||||
gdk_memory_depth_is_srgb (depth),
|
||||
width,
|
||||
height);
|
||||
|
||||
|
||||
@@ -243,6 +243,7 @@ gsk_vulkan_device_check_format (GskVulkanDevice *device,
|
||||
static GskVulkanImage *
|
||||
gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
GskGpuImageFlags required_flags,
|
||||
gsize width,
|
||||
gsize height,
|
||||
@@ -257,22 +258,42 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
GskVulkanImage *self;
|
||||
VkDevice vk_device;
|
||||
GskGpuImageFlags flags;
|
||||
VkFormat vk_format;
|
||||
VkFormat vk_format, vk_srgb_format;
|
||||
VkComponentMapping vk_components;
|
||||
|
||||
g_assert (width > 0 && height > 0);
|
||||
|
||||
vk_srgb_format = VK_FORMAT_UNDEFINED;
|
||||
|
||||
/* First, try the actual format */
|
||||
vk_format = gdk_memory_format_vk_format (format, &vk_components);
|
||||
if (!gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
if (try_srgb)
|
||||
vk_srgb_format = gdk_memory_format_vk_srgb_format (format);
|
||||
if (gsk_vulkan_device_check_format (device, vk_srgb_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
vk_format = vk_srgb_format;
|
||||
}
|
||||
else if (!gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
GdkMemoryFormat rgba_format;
|
||||
|
||||
/* Second, try the potential RGBA format */
|
||||
vk_format = gdk_memory_format_vk_rgba_format (format, NULL, &vk_components);
|
||||
if (!gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
vk_format = gdk_memory_format_vk_rgba_format (format, &rgba_format, &vk_components);
|
||||
if (try_srgb)
|
||||
vk_srgb_format = gdk_memory_format_vk_srgb_format (rgba_format);
|
||||
if (gsk_vulkan_device_check_format (device, vk_srgb_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
vk_format = vk_srgb_format;
|
||||
}
|
||||
else if (!gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
const GdkMemoryFormat *fallbacks;
|
||||
gsize i;
|
||||
@@ -282,9 +303,19 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
for (i = 0; fallbacks[i] != -1; i++)
|
||||
{
|
||||
vk_format = gdk_memory_format_vk_format (fallbacks[i], &vk_components);
|
||||
if (gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
if (try_srgb)
|
||||
vk_srgb_format = gdk_memory_format_vk_srgb_format (fallbacks[i]);
|
||||
if (gsk_vulkan_device_check_format (device, vk_srgb_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
vk_format = vk_srgb_format;
|
||||
format = fallbacks[i];
|
||||
break;
|
||||
}
|
||||
else if (gsk_vulkan_device_check_format (device, vk_format, &vk_components, required_flags,
|
||||
tiling, usage, width, height,
|
||||
&tiling, &flags))
|
||||
{
|
||||
format = fallbacks[i];
|
||||
break;
|
||||
@@ -297,6 +328,9 @@ gsk_vulkan_image_new (GskVulkanDevice *device,
|
||||
}
|
||||
}
|
||||
|
||||
if (vk_format == vk_srgb_format)
|
||||
flags |= GSK_GPU_IMAGE_SRGB;
|
||||
|
||||
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
flags |= GSK_GPU_IMAGE_STRAIGHT_ALPHA;
|
||||
|
||||
@@ -369,6 +403,7 @@ GskGpuImage *
|
||||
gsk_vulkan_image_new_for_upload (GskVulkanDevice *device,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
@@ -376,6 +411,7 @@ gsk_vulkan_image_new_for_upload (GskVulkanDevice *device,
|
||||
|
||||
self = gsk_vulkan_image_new (device,
|
||||
format,
|
||||
try_srgb,
|
||||
with_mipmap ? (GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_RENDERABLE | GSK_GPU_IMAGE_FILTERABLE) : 0,
|
||||
width,
|
||||
height,
|
||||
@@ -482,6 +518,7 @@ gsk_vulkan_image_new_for_atlas (GskVulkanDevice *device,
|
||||
|
||||
self = gsk_vulkan_image_new (device,
|
||||
GDK_MEMORY_DEFAULT,
|
||||
TRUE,
|
||||
GSK_GPU_IMAGE_FILTERABLE | GSK_GPU_IMAGE_RENDERABLE,
|
||||
width,
|
||||
height,
|
||||
@@ -499,6 +536,7 @@ GskGpuImage *
|
||||
gsk_vulkan_image_new_for_offscreen (GskVulkanDevice *device,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat preferred_format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
@@ -506,6 +544,7 @@ gsk_vulkan_image_new_for_offscreen (GskVulkanDevice *device,
|
||||
|
||||
self = gsk_vulkan_image_new (device,
|
||||
preferred_format,
|
||||
try_srgb,
|
||||
GSK_GPU_IMAGE_RENDERABLE |
|
||||
(with_mipmap ? GSK_GPU_IMAGE_CAN_MIPMAP | GSK_GPU_IMAGE_FILTERABLE : 0),
|
||||
width,
|
||||
@@ -623,12 +662,13 @@ gsk_vulkan_device_check_dmabuf_format (GskVulkanDevice *device,
|
||||
GskGpuImage *
|
||||
gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
uint64_t modifiers[100];
|
||||
VkDevice vk_device;
|
||||
VkFormat vk_format;
|
||||
VkFormat vk_format, vk_srgb_format;
|
||||
VkComponentMapping vk_components;
|
||||
VkMemoryRequirements requirements;
|
||||
GskVulkanImage *self;
|
||||
@@ -639,20 +679,41 @@ gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
|
||||
if (!gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_DMABUF))
|
||||
return NULL;
|
||||
|
||||
vk_srgb_format = VK_FORMAT_UNDEFINED;
|
||||
|
||||
vk_device = gsk_vulkan_device_get_vk_device (device);
|
||||
|
||||
/* First, try the actual format */
|
||||
vk_format = gdk_memory_format_vk_format (format, &vk_components);
|
||||
if (!gsk_vulkan_device_check_dmabuf_format (device, vk_format, &vk_components, width, height,
|
||||
modifiers, &flags, &n_modifiers))
|
||||
if (try_srgb)
|
||||
vk_srgb_format = gdk_memory_format_vk_srgb_format (format);
|
||||
if (gsk_vulkan_device_check_dmabuf_format (device, vk_srgb_format, &vk_components, width, height,
|
||||
modifiers, &flags, &n_modifiers))
|
||||
{
|
||||
vk_format = vk_srgb_format;
|
||||
}
|
||||
else if (!gsk_vulkan_device_check_dmabuf_format (device, vk_format, &vk_components, width, height,
|
||||
modifiers, &flags, &n_modifiers))
|
||||
{
|
||||
/* Second, try the potential RGBA format, but as a fallback */
|
||||
GdkMemoryFormat rgba_format;
|
||||
vk_format = gdk_memory_format_vk_rgba_format (format, &rgba_format, NULL);
|
||||
if (vk_format != VK_FORMAT_UNDEFINED)
|
||||
vk_format = gdk_memory_format_vk_format (rgba_format, &vk_components);
|
||||
if (gsk_vulkan_device_check_dmabuf_format (device, vk_format, &vk_components, width, height,
|
||||
{
|
||||
vk_format = gdk_memory_format_vk_format (rgba_format, &vk_components);
|
||||
if (try_srgb)
|
||||
vk_srgb_format = gdk_memory_format_vk_srgb_format (format);
|
||||
}
|
||||
else
|
||||
vk_srgb_format = VK_FORMAT_UNDEFINED;
|
||||
if (gsk_vulkan_device_check_dmabuf_format (device, vk_srgb_format, &vk_components, width, height,
|
||||
modifiers, &flags, &n_modifiers))
|
||||
{
|
||||
vk_format = vk_srgb_format;
|
||||
format = rgba_format;
|
||||
}
|
||||
else if (gsk_vulkan_device_check_dmabuf_format (device, vk_format, &vk_components, width, height,
|
||||
modifiers, &flags, &n_modifiers))
|
||||
{
|
||||
format = rgba_format;
|
||||
}
|
||||
@@ -666,8 +727,17 @@ gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
|
||||
for (i = 0; fallbacks[i] != -1; i++)
|
||||
{
|
||||
vk_format = gdk_memory_format_vk_format (fallbacks[i], &vk_components);
|
||||
if (gsk_vulkan_device_check_dmabuf_format (device, vk_format, &vk_components, width, height,
|
||||
if (try_srgb)
|
||||
vk_srgb_format = gdk_memory_format_vk_srgb_format (format);
|
||||
if (gsk_vulkan_device_check_dmabuf_format (device, vk_srgb_format, &vk_components, width, height,
|
||||
modifiers, &flags, &n_modifiers))
|
||||
{
|
||||
vk_format = vk_srgb_format;
|
||||
format = fallbacks[i];
|
||||
break;
|
||||
}
|
||||
else if (gsk_vulkan_device_check_dmabuf_format (device, vk_format, &vk_components, width, height,
|
||||
modifiers, &flags, &n_modifiers))
|
||||
{
|
||||
format = fallbacks[i];
|
||||
break;
|
||||
@@ -692,6 +762,7 @@ gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
|
||||
|
||||
gsk_gpu_image_setup (GSK_GPU_IMAGE (self),
|
||||
flags | GSK_GPU_IMAGE_EXTERNAL |
|
||||
(vk_format == vk_srgb_format ? GSK_GPU_IMAGE_SRGB : 0) |
|
||||
(gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT ? GSK_GPU_IMAGE_STRAIGHT_ALPHA : 0) |
|
||||
(gsk_component_mapping_is_framebuffer_compatible (&vk_components) ? 0 : GSK_GPU_IMAGE_NO_BLIT),
|
||||
format,
|
||||
|
||||
@@ -24,16 +24,19 @@ GskGpuImage * gsk_vulkan_image_new_for_atlas (GskVulk
|
||||
GskGpuImage * gsk_vulkan_image_new_for_offscreen (GskVulkanDevice *device,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat preferred_format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height);
|
||||
GskGpuImage * gsk_vulkan_image_new_for_upload (GskVulkanDevice *device,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height);
|
||||
#ifdef HAVE_DMABUF
|
||||
GskGpuImage * gsk_vulkan_image_new_dmabuf (GskVulkanDevice *device,
|
||||
GdkMemoryFormat format,
|
||||
gboolean try_srgb,
|
||||
gsize width,
|
||||
gsize height);
|
||||
GskGpuImage * gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
|
||||
|
||||
Reference in New Issue
Block a user