memoryformat: Take src_format and dest_format

Why do we need this? Because RGB images are provided in RGB format but
GPUs can't handle RGB, only RGBA, so we need to convert.

And we need to do that without allocating too much memory, because
allocating memory is slow. Which means in aprticular we need to do the
conversion after mipmapping, not before (like we were doing).
This commit is contained in:
Benjamin Otte 2024-08-27 05:59:54 +02:00 committed by Matthias Clasen
parent 848c6815d3
commit cea961f4f4
3 changed files with 36 additions and 5 deletions

View File

@ -2388,17 +2388,45 @@ gdk_memory_convert_color_state (guchar *data,
void
gdk_memory_mipmap (guchar *dest,
gsize dest_stride,
GdkMemoryFormat format,
GdkMemoryFormat dest_format,
const guchar *src,
gsize src_stride,
GdkMemoryFormat src_format,
gsize src_width,
gsize src_height,
guint lod_level)
{
const GdkMemoryFormatDescription *desc = &memory_formats[format];
const GdkMemoryFormatDescription *desc = &memory_formats[src_format];
g_assert (lod_level > 0);
desc->mipmap (dest, dest_stride, src, src_stride, src_width, src_height, lod_level);
if (dest_format == src_format)
{
desc->mipmap (dest, dest_stride, src, src_stride, src_width, src_height, lod_level);
}
else
{
gsize dest_width;
gsize size;
guchar *tmp;
gsize y, n;
n = 1 << lod_level;
dest_width = (src_width + n - 1) >> lod_level;
size = gdk_memory_format_bytes_per_pixel (src_format) * dest_width;
tmp = g_malloc (size);
for (y = 0; y < src_height; y += n)
{
desc->mipmap (tmp, (size + 7) & 7, src, src_stride, src_width, MIN (n, src_height - y), lod_level);
gdk_memory_convert (dest, dest_stride, dest_format, GDK_COLOR_STATE_SRGB,
tmp, (size + 7) & 7, src_format, GDK_COLOR_STATE_SRGB,
dest_width, 1);
dest += dest_stride;
src += n * src_stride;
}
g_free (tmp);
}
}

View File

@ -112,9 +112,10 @@ void gdk_memory_convert_color_state (guchar
gsize height);
void gdk_memory_mipmap (guchar *dest,
gsize dest_stride,
GdkMemoryFormat format,
GdkMemoryFormat dest_format,
const guchar *src,
gsize src_stride,
GdkMemoryFormat src_format,
gsize src_width,
gsize src_height,
guint lod_level);

View File

@ -251,10 +251,10 @@ gsk_gpu_upload_texture_op_draw (GskGpuOp *op,
GdkTextureDownloader *downloader;
downloader = gdk_texture_downloader_new (self->texture);
gdk_texture_downloader_set_format (downloader, gsk_gpu_image_get_format (self->image));
gdk_texture_downloader_set_color_state (downloader, gdk_texture_get_color_state (self->texture));
if (self->lod_level == 0)
{
gdk_texture_downloader_set_format (downloader, gsk_gpu_image_get_format (self->image));
gdk_texture_downloader_download_into (downloader, data, stride);
}
else
@ -262,12 +262,14 @@ gsk_gpu_upload_texture_op_draw (GskGpuOp *op,
GBytes *bytes;
gsize src_stride;
gdk_texture_downloader_set_format (downloader, gdk_texture_get_format (self->texture));
bytes = gdk_texture_downloader_download_bytes (downloader, &src_stride);
gdk_memory_mipmap (data,
stride,
gsk_gpu_image_get_format (self->image),
g_bytes_get_data (bytes, NULL),
src_stride,
gdk_texture_get_format (self->texture),
gdk_texture_get_width (self->texture),
gdk_texture_get_height (self->texture),
self->lod_level);