mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-08 17:50:10 +00:00
gpu: Allow uploading of mipmap levels when tiling
This allows uploading less memory but requires computing lod levels on the CPU which is slow because it reads through all of the memory and so far entirely not optimized. However, it uses significantly less VRAM. This is done by adding a gdk_memory_mipmap() function that does this task. The texture upload op now accepts a lod level and if that is >0 it uses gdk_memory_mipmap() on the source texture.
This commit is contained in:
parent
46559039f3
commit
848c6815d3
@ -22,7 +22,6 @@
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
|
||||
#include "gdkdmabuffourccprivate.h"
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkcolorstateprivate.h"
|
||||
#include "gdkparalleltaskprivate.h"
|
||||
#include "gtk/gtkcolorutilsprivate.h"
|
||||
@ -314,6 +313,61 @@ ADD_ALPHA_FUNC(r8g8b8_to_b8g8r8a8, 0, 1, 2, 2, 1, 0, 3)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_a8r8g8b8, 0, 1, 2, 1, 2, 3, 0)
|
||||
ADD_ALPHA_FUNC(r8g8b8_to_a8b8g8r8, 0, 1, 2, 3, 2, 1, 0)
|
||||
|
||||
#define MIPMAP_FUNC(SumType, DataType, n_units) \
|
||||
static void \
|
||||
gdk_mipmap_ ## DataType ## _ ## n_units (guchar *dest, \
|
||||
gsize dest_stride, \
|
||||
const guchar *src, \
|
||||
gsize src_stride, \
|
||||
gsize src_width, \
|
||||
gsize src_height, \
|
||||
guint lod_level) \
|
||||
{ \
|
||||
gsize y_dest, y, x_dest, x, i; \
|
||||
gsize n = 1 << lod_level; \
|
||||
\
|
||||
for (y_dest = 0; y_dest < src_height; y_dest += n) \
|
||||
{ \
|
||||
DataType *dest_data = (DataType *) dest; \
|
||||
for (x_dest = 0; x_dest < src_width; x_dest += n) \
|
||||
{ \
|
||||
SumType tmp[n_units] = { 0, }; \
|
||||
\
|
||||
for (y = 0; y < MIN (n, src_height - y_dest); y++) \
|
||||
{ \
|
||||
const DataType *src_data = (const DataType *) (src + y * src_stride); \
|
||||
for (x = 0; x < MIN (n, src_width - x_dest); x++) \
|
||||
{ \
|
||||
for (i = 0; i < n_units; i++) \
|
||||
tmp[i] += src_data[n_units * (x_dest + x) + i]; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
for (i = 0; i < n_units; i++) \
|
||||
*dest_data++ = tmp[i] / (x * y); \
|
||||
} \
|
||||
dest += dest_stride; \
|
||||
src += src_stride * n; \
|
||||
} \
|
||||
}
|
||||
|
||||
MIPMAP_FUNC(guint32, guint8, 1)
|
||||
MIPMAP_FUNC(guint32, guint8, 2)
|
||||
MIPMAP_FUNC(guint32, guint8, 3)
|
||||
MIPMAP_FUNC(guint32, guint8, 4)
|
||||
MIPMAP_FUNC(guint32, guint16, 1)
|
||||
MIPMAP_FUNC(guint32, guint16, 2)
|
||||
MIPMAP_FUNC(guint32, guint16, 3)
|
||||
MIPMAP_FUNC(guint32, guint16, 4)
|
||||
MIPMAP_FUNC(float, float, 1)
|
||||
MIPMAP_FUNC(float, float, 3)
|
||||
MIPMAP_FUNC(float, float, 4)
|
||||
#define half_float guint16
|
||||
MIPMAP_FUNC(float, half_float, 1)
|
||||
MIPMAP_FUNC(float, half_float, 3)
|
||||
MIPMAP_FUNC(float, half_float, 4)
|
||||
#undef half_float
|
||||
|
||||
struct _GdkMemoryFormatDescription
|
||||
{
|
||||
const char *name;
|
||||
@ -347,6 +401,7 @@ struct _GdkMemoryFormatDescription
|
||||
/* no premultiplication going on here */
|
||||
void (* to_float) (float (*)[4], const guchar*, gsize);
|
||||
void (* from_float) (guchar *, const float (*)[4], gsize);
|
||||
void (* mipmap) (guchar *, gsize, const guchar *, gsize, gsize, gsize, guint);
|
||||
};
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
@ -388,6 +443,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = b8g8r8a8_premultiplied_to_float,
|
||||
.from_float = b8g8r8a8_premultiplied_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = {
|
||||
.name = "ARGB8(p)",
|
||||
@ -419,6 +475,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = a8r8g8b8_premultiplied_to_float,
|
||||
.from_float = a8r8g8b8_premultiplied_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = {
|
||||
.name = "RGBA8(p)",
|
||||
@ -449,6 +506,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r8g8b8a8_premultiplied_to_float,
|
||||
.from_float = r8g8b8a8_premultiplied_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] = {
|
||||
.name = "ABGR8(p)",
|
||||
@ -480,6 +538,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = a8b8g8r8_premultiplied_to_float,
|
||||
.from_float = a8b8g8r8_premultiplied_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_B8G8R8A8] = {
|
||||
.name = "BGRA8",
|
||||
@ -511,6 +570,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = b8g8r8a8_to_float,
|
||||
.from_float = b8g8r8a8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_A8R8G8B8] = {
|
||||
.name = "ARGB8",
|
||||
@ -542,6 +602,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = a8r8g8b8_to_float,
|
||||
.from_float = a8r8g8b8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_R8G8B8A8] = {
|
||||
.name = "RGBA8",
|
||||
@ -572,6 +633,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r8g8b8a8_to_float,
|
||||
.from_float = r8g8b8a8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_A8B8G8R8] = {
|
||||
.name = "ABGR8",
|
||||
@ -603,6 +665,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = a8b8g8r8_to_float,
|
||||
.from_float = a8b8g8r8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_B8G8R8X8] = {
|
||||
.name = "BGRX8",
|
||||
@ -635,6 +698,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = b8g8r8x8_to_float,
|
||||
.from_float = b8g8r8x8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_X8R8G8B8] = {
|
||||
.name = "XRGB8",
|
||||
@ -667,6 +731,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = x8r8g8b8_to_float,
|
||||
.from_float = x8r8g8b8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_R8G8B8X8] = {
|
||||
.name = "RGBX8",
|
||||
@ -698,6 +763,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r8g8b8x8_to_float,
|
||||
.from_float = r8g8b8x8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_X8B8G8R8] = {
|
||||
.name = "XBGR8",
|
||||
@ -730,6 +796,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = x8b8g8r8_to_float,
|
||||
.from_float = x8b8g8r8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_4,
|
||||
},
|
||||
[GDK_MEMORY_R8G8B8] = {
|
||||
.name = "RGB8",
|
||||
@ -761,6 +828,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r8g8b8_to_float,
|
||||
.from_float = r8g8b8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_3,
|
||||
},
|
||||
[GDK_MEMORY_B8G8R8] = {
|
||||
.name = "BGR8",
|
||||
@ -793,6 +861,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = b8g8r8_to_float,
|
||||
.from_float = b8g8r8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_3,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16] = {
|
||||
.name = "RGB16",
|
||||
@ -827,6 +896,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r16g16b16_to_float,
|
||||
.from_float = r16g16b16_from_float,
|
||||
.mipmap = gdk_mipmap_guint16_3,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = {
|
||||
.name = "RGBA16(p)",
|
||||
@ -860,6 +930,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r16g16b16a16_to_float,
|
||||
.from_float = r16g16b16a16_from_float,
|
||||
.mipmap = gdk_mipmap_guint16_4,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16] = {
|
||||
.name = "RGBA16",
|
||||
@ -893,6 +964,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r16g16b16a16_to_float,
|
||||
.from_float = r16g16b16a16_from_float,
|
||||
.mipmap = gdk_mipmap_guint16_4,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16_FLOAT] = {
|
||||
.name = "RGBA16f",
|
||||
@ -926,6 +998,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r16g16b16_float_to_float,
|
||||
.from_float = r16g16b16_float_from_float,
|
||||
.mipmap = gdk_mipmap_half_float_3,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = {
|
||||
.name = "RGBA16f(p)",
|
||||
@ -958,6 +1031,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r16g16b16a16_float_to_float,
|
||||
.from_float = r16g16b16a16_float_from_float,
|
||||
.mipmap = gdk_mipmap_half_float_4,
|
||||
},
|
||||
[GDK_MEMORY_R16G16B16A16_FLOAT] = {
|
||||
.name = "RGBA16f",
|
||||
@ -990,6 +1064,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r16g16b16a16_float_to_float,
|
||||
.from_float = r16g16b16a16_float_from_float,
|
||||
.mipmap = gdk_mipmap_half_float_4,
|
||||
},
|
||||
[GDK_MEMORY_R32G32B32_FLOAT] = {
|
||||
.name = "RGB32f",
|
||||
@ -1023,6 +1098,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r32g32b32_float_to_float,
|
||||
.from_float = r32g32b32_float_from_float,
|
||||
.mipmap = gdk_mipmap_float_3,
|
||||
},
|
||||
[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = {
|
||||
.name = "RGBA32f(p)",
|
||||
@ -1055,6 +1131,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r32g32b32a32_float_to_float,
|
||||
.from_float = r32g32b32a32_float_from_float,
|
||||
.mipmap = gdk_mipmap_float_4,
|
||||
},
|
||||
[GDK_MEMORY_R32G32B32A32_FLOAT] = {
|
||||
.name = "RGBA32f",
|
||||
@ -1087,6 +1164,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = r32g32b32a32_float_to_float,
|
||||
.from_float = r32g32b32a32_float_from_float,
|
||||
.mipmap = gdk_mipmap_float_4,
|
||||
},
|
||||
[GDK_MEMORY_G8A8_PREMULTIPLIED] = {
|
||||
.name = "GA8(p)",
|
||||
@ -1118,6 +1196,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = g8a8_premultiplied_to_float,
|
||||
.from_float = g8a8_premultiplied_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_2,
|
||||
},
|
||||
[GDK_MEMORY_G8A8] = {
|
||||
.name = "GA8",
|
||||
@ -1149,6 +1228,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = g8a8_to_float,
|
||||
.from_float = g8a8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_2,
|
||||
},
|
||||
[GDK_MEMORY_G8] = {
|
||||
.name = "G8",
|
||||
@ -1180,6 +1260,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = g8_to_float,
|
||||
.from_float = g8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_1,
|
||||
},
|
||||
[GDK_MEMORY_G16A16_PREMULTIPLIED] = {
|
||||
.name = "GA16(p)",
|
||||
@ -1214,6 +1295,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = g16a16_premultiplied_to_float,
|
||||
.from_float = g16a16_premultiplied_from_float,
|
||||
.mipmap = gdk_mipmap_guint16_2,
|
||||
},
|
||||
[GDK_MEMORY_G16A16] = {
|
||||
.name = "GA16",
|
||||
@ -1248,6 +1330,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = g16a16_to_float,
|
||||
.from_float = g16a16_from_float,
|
||||
.mipmap = gdk_mipmap_guint16_2,
|
||||
},
|
||||
[GDK_MEMORY_G16] = {
|
||||
.name = "G16",
|
||||
@ -1282,6 +1365,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = g16_to_float,
|
||||
.from_float = g16_from_float,
|
||||
.mipmap = gdk_mipmap_guint16_1,
|
||||
},
|
||||
[GDK_MEMORY_A8] = {
|
||||
.name = "A8",
|
||||
@ -1313,6 +1397,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = a8_to_float,
|
||||
.from_float = a8_from_float,
|
||||
.mipmap = gdk_mipmap_guint8_1,
|
||||
},
|
||||
[GDK_MEMORY_A16] = {
|
||||
.name = "A16",
|
||||
@ -1347,6 +1432,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = a16_to_float,
|
||||
.from_float = a16_from_float,
|
||||
.mipmap = gdk_mipmap_guint16_1,
|
||||
},
|
||||
[GDK_MEMORY_A16_FLOAT] = {
|
||||
.name = "A16f",
|
||||
@ -1380,6 +1466,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = a16_float_to_float,
|
||||
.from_float = a16_float_from_float,
|
||||
.mipmap = gdk_mipmap_half_float_1,
|
||||
},
|
||||
[GDK_MEMORY_A32_FLOAT] = {
|
||||
.name = "A32f",
|
||||
@ -1413,6 +1500,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
#endif
|
||||
.to_float = a32_float_to_float,
|
||||
.from_float = a32_float_from_float,
|
||||
.mipmap = gdk_mipmap_float_1,
|
||||
}
|
||||
};
|
||||
|
||||
@ -2296,3 +2384,21 @@ gdk_memory_convert_color_state (guchar *data,
|
||||
gdk_parallel_task_run (gdk_memory_convert_color_state_generic, &mc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gdk_memory_mipmap (guchar *dest,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat format,
|
||||
const guchar *src,
|
||||
gsize src_stride,
|
||||
gsize src_width,
|
||||
gsize src_height,
|
||||
guint lod_level)
|
||||
{
|
||||
const GdkMemoryFormatDescription *desc = &memory_formats[format];
|
||||
|
||||
g_assert (lod_level > 0);
|
||||
|
||||
desc->mipmap (dest, dest_stride, src, src_stride, src_width, src_height, lod_level);
|
||||
}
|
||||
|
||||
|
@ -110,6 +110,14 @@ void gdk_memory_convert_color_state (guchar
|
||||
GdkColorState *dest_color_state,
|
||||
gsize width,
|
||||
gsize height);
|
||||
void gdk_memory_mipmap (guchar *dest,
|
||||
gsize dest_stride,
|
||||
GdkMemoryFormat format,
|
||||
const guchar *src,
|
||||
gsize src_stride,
|
||||
gsize src_width,
|
||||
gsize src_height,
|
||||
guint lod_level);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -537,6 +537,7 @@ struct _GskGpuCachedTile
|
||||
GskGpuCached parent;
|
||||
|
||||
GdkTexture *texture;
|
||||
guint lod_level;
|
||||
gsize tile_id;
|
||||
|
||||
/* atomic */ int use_count; /* We count the use by the cache (via the linked
|
||||
@ -630,7 +631,7 @@ gsk_gpu_cached_tile_hash (gconstpointer data)
|
||||
{
|
||||
const GskGpuCachedTile *self = data;
|
||||
|
||||
return g_direct_hash (self->texture) ^ self->tile_id;
|
||||
return g_direct_hash (self->texture) ^ self->tile_id ^ (self->lod_level << 24);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -641,12 +642,14 @@ gsk_gpu_cached_tile_equal (gconstpointer data_a,
|
||||
const GskGpuCachedTile *b = data_b;
|
||||
|
||||
return a->texture == b->texture &&
|
||||
a->lod_level == b->lod_level &&
|
||||
a->tile_id == b->tile_id;
|
||||
}
|
||||
|
||||
static GskGpuCachedTile *
|
||||
gsk_gpu_cached_tile_new (GskGpuCache *cache,
|
||||
GdkTexture *texture,
|
||||
guint lod_level,
|
||||
guint tile_id,
|
||||
GskGpuImage *image,
|
||||
GdkColorState *color_state)
|
||||
@ -655,6 +658,7 @@ gsk_gpu_cached_tile_new (GskGpuCache *cache,
|
||||
|
||||
self = gsk_gpu_cached_new (cache, &GSK_GPU_CACHED_TILE_CLASS);
|
||||
self->texture = texture;
|
||||
self->lod_level = lod_level;
|
||||
self->tile_id = tile_id;
|
||||
self->image = g_object_ref (image);
|
||||
self->color_state = gdk_color_state_ref (color_state);
|
||||
@ -675,12 +679,14 @@ gsk_gpu_cached_tile_new (GskGpuCache *cache,
|
||||
GskGpuImage *
|
||||
gsk_gpu_cache_lookup_tile (GskGpuCache *self,
|
||||
GdkTexture *texture,
|
||||
guint lod_level,
|
||||
gsize tile_id,
|
||||
GdkColorState **out_color_state)
|
||||
{
|
||||
GskGpuCachedTile *tile;
|
||||
GskGpuCachedTile lookup = {
|
||||
.texture = texture,
|
||||
.lod_level = lod_level,
|
||||
.tile_id = tile_id
|
||||
};
|
||||
|
||||
@ -701,13 +707,14 @@ gsk_gpu_cache_lookup_tile (GskGpuCache *self,
|
||||
void
|
||||
gsk_gpu_cache_cache_tile (GskGpuCache *self,
|
||||
GdkTexture *texture,
|
||||
guint tile_id,
|
||||
guint lod_level,
|
||||
gsize tile_id,
|
||||
GskGpuImage *image,
|
||||
GdkColorState *color_state)
|
||||
{
|
||||
GskGpuCachedTile *tile;
|
||||
|
||||
tile = gsk_gpu_cached_tile_new (self, texture, tile_id, image, color_state);
|
||||
tile = gsk_gpu_cached_tile_new (self, texture, lod_level, tile_id, image, color_state);
|
||||
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) tile);
|
||||
}
|
||||
|
@ -77,11 +77,13 @@ void gsk_gpu_cache_cache_texture_image (GskGpuC
|
||||
GdkColorState *color_state);
|
||||
GskGpuImage * gsk_gpu_cache_lookup_tile (GskGpuCache *self,
|
||||
GdkTexture *texture,
|
||||
guint lod_level,
|
||||
gsize tile_id,
|
||||
GdkColorState **out_color_state);
|
||||
void gsk_gpu_cache_cache_tile (GskGpuCache *self,
|
||||
GdkTexture *texture,
|
||||
guint tile_id,
|
||||
guint lod_level,
|
||||
gsize tile_id,
|
||||
GskGpuImage *image,
|
||||
GdkColorState *color_state);
|
||||
|
||||
|
@ -107,7 +107,7 @@ gsk_gpu_frame_default_upload_texture (GskGpuFrame *self,
|
||||
{
|
||||
GskGpuImage *image;
|
||||
|
||||
image = gsk_gpu_upload_texture_op_try (self, with_mipmap, texture);
|
||||
image = gsk_gpu_upload_texture_op_try (self, with_mipmap, 0, texture);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
@ -1964,18 +1964,26 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
gboolean need_mipmap;
|
||||
GdkMemoryTexture *memtex;
|
||||
GdkTexture *subtex;
|
||||
float scaled_tile_width, scaled_tile_height;
|
||||
float scale_factor, scaled_tile_width, scaled_tile_height;
|
||||
gsize tile_size, width, height, n_width, n_height, x, y;
|
||||
graphene_rect_t clip_bounds;
|
||||
guint lod_level;
|
||||
|
||||
device = gsk_gpu_frame_get_device (self->frame);
|
||||
cache = gsk_gpu_device_get_cache (device);
|
||||
sampler = gsk_gpu_sampler_for_scaling_filter (scaling_filter);
|
||||
need_mipmap = scaling_filter == GSK_SCALING_FILTER_TRILINEAR;
|
||||
gsk_gpu_node_processor_get_clip_bounds (self, &clip_bounds);
|
||||
tile_size = gsk_gpu_device_get_tile_size (device);
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
tile_size = gsk_gpu_device_get_tile_size (device);
|
||||
scale_factor = MIN (width / MAX (tile_size, texture_bounds->size.width),
|
||||
height / MAX (tile_size, texture_bounds->size.height));
|
||||
if (scale_factor <= 1.0)
|
||||
lod_level = 0;
|
||||
else
|
||||
lod_level = floor (log2f (scale_factor));
|
||||
tile_size <<= lod_level;
|
||||
n_width = (width + tile_size - 1) / tile_size;
|
||||
n_height = (height + tile_size - 1) / tile_size;
|
||||
scaled_tile_width = texture_bounds->size.width * tile_size / width;
|
||||
@ -1994,7 +2002,7 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
!gsk_rect_intersects (&clip_bounds, &tile_rect))
|
||||
continue;
|
||||
|
||||
tile = gsk_gpu_cache_lookup_tile (cache, texture, y * n_width + x, &tile_cs);
|
||||
tile = gsk_gpu_cache_lookup_tile (cache, texture, lod_level, y * n_width + x, &tile_cs);
|
||||
|
||||
if (tile == NULL)
|
||||
{
|
||||
@ -2005,7 +2013,7 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
y * tile_size,
|
||||
MIN (tile_size, width - x * tile_size),
|
||||
MIN (tile_size, height - y * tile_size));
|
||||
tile = gsk_gpu_upload_texture_op_try (self->frame, need_mipmap, subtex);
|
||||
tile = gsk_gpu_upload_texture_op_try (self->frame, need_mipmap, lod_level, subtex);
|
||||
g_object_unref (subtex);
|
||||
if (tile == NULL)
|
||||
{
|
||||
@ -2021,7 +2029,7 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
g_assert (tile_cs);
|
||||
}
|
||||
|
||||
gsk_gpu_cache_cache_tile (cache, texture, y * n_width + x, tile, tile_cs);
|
||||
gsk_gpu_cache_cache_tile (cache, texture, lod_level, y * n_width + x, tile, tile_cs);
|
||||
}
|
||||
|
||||
if (need_mipmap &&
|
||||
@ -2029,7 +2037,7 @@ gsk_gpu_node_processor_draw_texture_tiles (GskGpuNodeProcessor *self,
|
||||
{
|
||||
tile = gsk_gpu_copy_image (self->frame, self->ccs, tile, tile_cs, TRUE);
|
||||
tile_cs = self->ccs;
|
||||
gsk_gpu_cache_cache_tile (cache, texture, y * n_width + x, tile, tile_cs);
|
||||
gsk_gpu_cache_cache_tile (cache, texture, lod_level, y * n_width + x, tile, tile_cs);
|
||||
}
|
||||
if (need_mipmap && !(gsk_gpu_image_get_flags (tile) & GSK_GPU_IMAGE_MIPMAP))
|
||||
gsk_gpu_mipmap_op (self->frame, tile);
|
||||
|
@ -214,6 +214,7 @@ struct _GskGpuUploadTextureOp
|
||||
GskGpuImage *image;
|
||||
GskGpuBuffer *buffer;
|
||||
GdkTexture *texture;
|
||||
guint lod_level;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -236,6 +237,8 @@ gsk_gpu_upload_texture_op_print (GskGpuOp *op,
|
||||
|
||||
gsk_gpu_print_op (string, indent, "upload-texture");
|
||||
gsk_gpu_print_image (string, self->image);
|
||||
if (self->lod_level > 0)
|
||||
g_string_append_printf (string, " @%ux ", 1 << self->lod_level);
|
||||
gsk_gpu_print_newline (string);
|
||||
}
|
||||
|
||||
@ -250,7 +253,26 @@ gsk_gpu_upload_texture_op_draw (GskGpuOp *op,
|
||||
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));
|
||||
gdk_texture_downloader_download_into (downloader, data, stride);
|
||||
if (self->lod_level == 0)
|
||||
{
|
||||
gdk_texture_downloader_download_into (downloader, data, stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
GBytes *bytes;
|
||||
gsize src_stride;
|
||||
|
||||
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_width (self->texture),
|
||||
gdk_texture_get_height (self->texture),
|
||||
self->lod_level);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
gdk_texture_downloader_free (downloader);
|
||||
}
|
||||
|
||||
@ -298,6 +320,7 @@ static const GskGpuOpClass GSK_GPU_UPLOAD_TEXTURE_OP_CLASS = {
|
||||
GskGpuImage *
|
||||
gsk_gpu_upload_texture_op_try (GskGpuFrame *frame,
|
||||
gboolean with_mipmap,
|
||||
guint lod_level,
|
||||
GdkTexture *texture)
|
||||
{
|
||||
GskGpuUploadTextureOp *self;
|
||||
@ -311,8 +334,8 @@ gsk_gpu_upload_texture_op_try (GskGpuFrame *frame,
|
||||
format,
|
||||
gdk_memory_format_alpha (format) != GDK_MEMORY_ALPHA_PREMULTIPLIED &&
|
||||
gdk_color_state_get_no_srgb_tf (gdk_texture_get_color_state (texture)) != NULL,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture));
|
||||
(gdk_texture_get_width (texture) + (1 << lod_level) - 1) >> lod_level,
|
||||
(gdk_texture_get_height (texture) + (1 << lod_level) - 1) >> lod_level);
|
||||
if (image == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -343,6 +366,7 @@ gsk_gpu_upload_texture_op_try (GskGpuFrame *frame,
|
||||
self = (GskGpuUploadTextureOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_UPLOAD_TEXTURE_OP_CLASS);
|
||||
|
||||
self->texture = g_object_ref (texture);
|
||||
self->lod_level = lod_level;
|
||||
self->image = image;
|
||||
|
||||
return g_object_ref (self->image);
|
||||
|
@ -11,6 +11,7 @@ typedef void (* GskGpuCairoFunc) (gpointe
|
||||
|
||||
GskGpuImage * gsk_gpu_upload_texture_op_try (GskGpuFrame *frame,
|
||||
gboolean with_mipmap,
|
||||
guint lod_level,
|
||||
GdkTexture *texture);
|
||||
|
||||
GskGpuImage * gsk_gpu_upload_cairo_op (GskGpuFrame *frame,
|
||||
|
Loading…
Reference in New Issue
Block a user