mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-08 17:50:10 +00:00
gl: Track if mipmap generation is allowed
... and if it isn't, switch to a format that does allow mipmaps.
This commit is contained in:
parent
b830ca8fab
commit
96a71d515b
@ -1477,12 +1477,14 @@ gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self)
|
||||
static GdkMemoryFormat
|
||||
memory_format_gl_format (GskGLCommandQueue *self,
|
||||
GdkMemoryFormat data_format,
|
||||
gboolean ensure_mipmap,
|
||||
gboolean *out_can_mipmap,
|
||||
GLint *gl_internalformat,
|
||||
GLenum *gl_format,
|
||||
GLenum *gl_type,
|
||||
GLint gl_swizzle[4])
|
||||
{
|
||||
GdkGLMemoryFlags flags;
|
||||
GdkGLMemoryFlags flags, required_flags;
|
||||
GdkMemoryFormat alt_format;
|
||||
const GdkMemoryFormat *fallbacks;
|
||||
gsize i;
|
||||
@ -1491,15 +1493,20 @@ memory_format_gl_format (GskGLCommandQueue *self,
|
||||
if (gdk_memory_format_alpha (data_format) == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
data_format = gdk_memory_format_get_premultiplied (data_format);
|
||||
|
||||
required_flags = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
if (ensure_mipmap)
|
||||
required_flags |= GDK_GL_FORMAT_RENDERABLE;
|
||||
|
||||
/* First, try the format itself */
|
||||
flags = gdk_gl_context_get_format_flags (self->context, data_format);
|
||||
if ((flags & (GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE)) == (GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE))
|
||||
if ((flags & required_flags) == required_flags)
|
||||
{
|
||||
gdk_memory_format_gl_format (data_format,
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
gl_type,
|
||||
gl_swizzle);
|
||||
*out_can_mipmap = (flags & GDK_GL_FORMAT_RENDERABLE) ? TRUE : FALSE;
|
||||
return data_format;
|
||||
}
|
||||
|
||||
@ -1512,8 +1519,10 @@ memory_format_gl_format (GskGLCommandQueue *self,
|
||||
gl_swizzle))
|
||||
{
|
||||
flags = gdk_gl_context_get_format_flags (self->context, alt_format);
|
||||
if ((flags & (GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE)) == (GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE))
|
||||
if ((flags & required_flags) == required_flags)
|
||||
{
|
||||
*out_can_mipmap = (flags & GDK_GL_FORMAT_RENDERABLE) ? TRUE : FALSE;
|
||||
|
||||
if (self->can_swizzle)
|
||||
return data_format;
|
||||
|
||||
@ -1532,13 +1541,15 @@ memory_format_gl_format (GskGLCommandQueue *self,
|
||||
for (i = 0; fallbacks[i] != -1; i++)
|
||||
{
|
||||
flags = gdk_gl_context_get_format_flags (self->context, fallbacks[i]);
|
||||
if (((flags & (GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE)) == (GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE)))
|
||||
if (((flags & required_flags) == required_flags))
|
||||
{
|
||||
gdk_memory_format_gl_format (fallbacks[i],
|
||||
gl_internalformat,
|
||||
gl_format,
|
||||
gl_type,
|
||||
gl_swizzle);
|
||||
|
||||
*out_can_mipmap = (flags & GDK_GL_FORMAT_RENDERABLE) ? TRUE : FALSE;
|
||||
return fallbacks[i];
|
||||
}
|
||||
}
|
||||
@ -1644,8 +1655,10 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
|
||||
|
||||
int
|
||||
gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
|
||||
gboolean ensure_mipmap,
|
||||
unsigned int n_chunks,
|
||||
GskGLTextureChunk *chunks)
|
||||
GskGLTextureChunk *chunks,
|
||||
gboolean *out_can_mipmap)
|
||||
{
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
int width, height;
|
||||
@ -1690,6 +1703,8 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
|
||||
data_format = gdk_texture_get_format (chunks[0].texture);
|
||||
data_format = memory_format_gl_format (self,
|
||||
data_format,
|
||||
ensure_mipmap,
|
||||
out_can_mipmap,
|
||||
&gl_internalformat,
|
||||
&gl_format,
|
||||
&gl_type,
|
||||
@ -1718,9 +1733,15 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
|
||||
|
||||
int
|
||||
gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
GdkTexture *texture)
|
||||
GdkTexture *texture,
|
||||
gboolean ensure_mipmap,
|
||||
gboolean *out_can_mipmap)
|
||||
{
|
||||
return gsk_gl_command_queue_upload_texture_chunks (self, 1, &(GskGLTextureChunk){ texture, 0, 0});
|
||||
return gsk_gl_command_queue_upload_texture_chunks (self,
|
||||
ensure_mipmap,
|
||||
1,
|
||||
&(GskGLTextureChunk){ texture, 0, 0},
|
||||
out_can_mipmap);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -313,7 +313,9 @@ void gsk_gl_command_queue_execute (GskGLCommandQueue
|
||||
const cairo_region_t *scissor,
|
||||
guint default_framebuffer);
|
||||
int gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
GdkTexture *texture);
|
||||
GdkTexture *texture,
|
||||
gboolean ensure_mipmap,
|
||||
gboolean *out_can_mipmap);
|
||||
int gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
int width,
|
||||
int height,
|
||||
@ -327,8 +329,10 @@ typedef struct {
|
||||
} GskGLTextureChunk;
|
||||
|
||||
int gsk_gl_command_queue_upload_texture_chunks(GskGLCommandQueue *self,
|
||||
gboolean ensure_mipmap,
|
||||
unsigned int n_chunks,
|
||||
GskGLTextureChunk *chunks);
|
||||
GskGLTextureChunk *chunks,
|
||||
gboolean *out_can_mipmap);
|
||||
|
||||
guint gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self);
|
||||
gboolean gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
|
||||
|
@ -925,6 +925,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
guint texture_id;
|
||||
int height;
|
||||
int width;
|
||||
gboolean can_mipmap = FALSE;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), 0);
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), 0);
|
||||
@ -938,7 +939,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
t = gdk_texture_get_render_data (texture, self);
|
||||
if (t && t->texture_id)
|
||||
{
|
||||
if (ensure_mipmap && !t->has_mipmap)
|
||||
if (ensure_mipmap && t->can_mipmap && !t->has_mipmap)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, t->texture_id);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
@ -948,7 +949,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
return t->texture_id;
|
||||
}
|
||||
|
||||
if (GDK_IS_DMABUF_TEXTURE (texture))
|
||||
if (GDK_IS_DMABUF_TEXTURE (texture) && !ensure_mipmap)
|
||||
{
|
||||
texture_id = gsk_gl_driver_import_dmabuf_texture (self, GDK_DMABUF_TEXTURE (texture));
|
||||
}
|
||||
@ -975,7 +976,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
*/
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, GDK_TEXTURE (downloaded_texture));
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, GDK_TEXTURE (downloaded_texture), ensure_mipmap, &can_mipmap);
|
||||
}
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
@ -984,8 +985,10 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
t = gsk_gl_texture_new (texture_id,
|
||||
width, height,
|
||||
self->current_frame_id);
|
||||
t->can_mipmap = can_mipmap;
|
||||
if (ensure_mipmap)
|
||||
{
|
||||
g_assert (can_mipmap);
|
||||
glBindTexture (GL_TEXTURE_2D, t->texture_id);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
t->has_mipmap = TRUE;
|
||||
@ -1433,6 +1436,7 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
GdkMemoryTexture *memtex2 = NULL;
|
||||
GdkMemoryTexture *memtex3 = NULL;
|
||||
GdkMemoryTexture *memtex4 = NULL;
|
||||
gboolean can_mipmap = TRUE, slice_can_mipmap;
|
||||
|
||||
g_assert (GSK_IS_GL_DRIVER (self));
|
||||
g_assert (GDK_IS_TEXTURE (texture));
|
||||
@ -1694,7 +1698,7 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
n_chunks++;
|
||||
}
|
||||
|
||||
texture_id = gsk_gl_command_queue_upload_texture_chunks (self->command_queue, n_chunks, chunks);
|
||||
texture_id = gsk_gl_command_queue_upload_texture_chunks (self->command_queue, TRUE, n_chunks, chunks, &slice_can_mipmap);
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
@ -1707,10 +1711,12 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
GdkTexture *subtex;
|
||||
|
||||
subtex = gdk_memory_texture_new_subtexture (memtex, x, y, slice_width, slice_height);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, subtex);
|
||||
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, subtex, FALSE, &slice_can_mipmap);
|
||||
g_object_unref (subtex);
|
||||
}
|
||||
|
||||
can_mipmap &= slice_can_mipmap;
|
||||
|
||||
slices[slice_index].rect.x = x;
|
||||
slices[slice_index].rect.y = y;
|
||||
slices[slice_index].rect.width = slice_width;
|
||||
@ -1737,6 +1743,7 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
|
||||
t = gsk_gl_texture_new (0,
|
||||
tex_width, tex_height,
|
||||
self->current_frame_id);
|
||||
t->can_mipmap = can_mipmap;
|
||||
t->has_mipmap = ensure_mipmap;
|
||||
|
||||
/* Use gsk_gl_texture_free() as destroy notify here since we are
|
||||
|
@ -73,6 +73,8 @@ struct _GskGLTexture
|
||||
|
||||
/* Set when used by an atlas so we don't drop the texture */
|
||||
guint permanent : 1;
|
||||
/* we are allowed to call glGenerateMipmap() for this texture */
|
||||
guint can_mipmap : 1;
|
||||
/* we called glGenerateMipmap() for this texture */
|
||||
guint has_mipmap : 1;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user