mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
Merge branch 'mipmap-tracking' into 'main'
gsk: Avoid copying GL texture in more cases See merge request GNOME/gtk!5704
This commit is contained in:
commit
65acf8500f
@ -38,6 +38,7 @@ struct _GdkGLTexture {
|
||||
|
||||
GdkGLContext *context;
|
||||
guint id;
|
||||
gboolean has_mipmap;
|
||||
|
||||
GdkTexture *saved;
|
||||
|
||||
@ -284,6 +285,12 @@ gdk_gl_texture_get_id (GdkGLTexture *self)
|
||||
return self->id;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_gl_texture_has_mipmap (GdkGLTexture *self)
|
||||
{
|
||||
return self->has_mipmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_release:
|
||||
* @self: a `GdkTexture` wrapping a GL texture
|
||||
@ -315,13 +322,15 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
GdkTexture *texture = GDK_TEXTURE (self);
|
||||
GLint active_texture;
|
||||
GLint internal_format;
|
||||
GLint width, height;
|
||||
|
||||
/* Abort if somebody else is GL-ing here... */
|
||||
if (self->context != gdk_gl_context_get_current () ||
|
||||
if (!gdk_gl_context_is_shared (self->context, gdk_gl_context_get_current ()) ||
|
||||
/* ... or glGetTexLevelParameter() isn't supported */
|
||||
!gdk_gl_context_check_version (self->context, 0, 0, 3, 1))
|
||||
!gdk_gl_context_check_version (gdk_gl_context_get_current (), 0, 0, 3, 1))
|
||||
{
|
||||
texture->format = GDK_MEMORY_DEFAULT;
|
||||
self->has_mipmap = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -411,6 +420,20 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Determine if the texture has a mipmap.
|
||||
* We do this here, since it requires binding the texture,
|
||||
* and we're already doing that here.
|
||||
* GL has no way to directly query 'mipmap completeness' of textures,
|
||||
* so we just check that level 1 has the expected size, and assume
|
||||
* that means somebody called glGenerateMipmap().
|
||||
*/
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 1, GL_TEXTURE_WIDTH, &width);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 1, GL_TEXTURE_HEIGHT, &height);
|
||||
|
||||
self->has_mipmap = width == texture->width / 2 &&
|
||||
height == texture->height / 2;
|
||||
|
||||
/* restore previous state */
|
||||
glBindTexture (GL_TEXTURE_2D, active_texture);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ G_BEGIN_DECLS
|
||||
|
||||
GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self);
|
||||
guint gdk_gl_texture_get_id (GdkGLTexture *self);
|
||||
gboolean gdk_gl_texture_has_mipmap (GdkGLTexture *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -744,12 +744,13 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
return t->texture_id;
|
||||
}
|
||||
|
||||
if (GDK_IS_GL_TEXTURE (texture) && !ensure_mipmap)
|
||||
if (GDK_IS_GL_TEXTURE (texture))
|
||||
{
|
||||
GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
|
||||
GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
|
||||
|
||||
if (gdk_gl_context_is_shared (context, texture_context))
|
||||
if (gdk_gl_context_is_shared (context, texture_context) &&
|
||||
(!ensure_mipmap || gdk_gl_texture_has_mipmap (gl_texture)))
|
||||
{
|
||||
/* A GL texture from the same GL context is a simple task... */
|
||||
return gdk_gl_texture_get_id (gl_texture);
|
||||
|
@ -201,6 +201,7 @@ typedef struct _GskGLRenderOffscreen
|
||||
|
||||
/* Return location for whether we created a texture */
|
||||
guint was_offscreen : 1;
|
||||
guint has_mipmap : 1;
|
||||
} GskGLRenderOffscreen;
|
||||
|
||||
static void gsk_gl_render_job_visit_node (GskGLRenderJob *job,
|
||||
@ -3513,22 +3514,36 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
|
||||
gboolean ensure_mipmap,
|
||||
GskGLRenderOffscreen *offscreen)
|
||||
{
|
||||
GdkGLTexture *gl_texture = NULL;
|
||||
|
||||
if (GDK_IS_GL_TEXTURE (texture))
|
||||
gl_texture = GDK_GL_TEXTURE (texture);
|
||||
|
||||
if (!ensure_mipmap &&
|
||||
gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
|
||||
texture->width,
|
||||
texture->height) &&
|
||||
!GDK_IS_GL_TEXTURE (texture))
|
||||
!gl_texture)
|
||||
{
|
||||
const GskGLIconData *icon_data;
|
||||
|
||||
gsk_gl_icon_library_lookup_or_add (job->driver->icons_library, texture, &icon_data);
|
||||
offscreen->texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data);
|
||||
memcpy (&offscreen->area, &icon_data->entry.area, sizeof offscreen->area);
|
||||
offscreen->has_mipmap = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Only generate a mipmap if it does not make use reupload
|
||||
* a GL texture which we could otherwise use directly.
|
||||
*/
|
||||
if (gl_texture &&
|
||||
gdk_gl_context_is_shared (gdk_gl_texture_get_context (gl_texture), job->command_queue->context))
|
||||
ensure_mipmap = gdk_gl_texture_has_mipmap (gl_texture);
|
||||
|
||||
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, ensure_mipmap);
|
||||
init_full_texture_region (offscreen);
|
||||
offscreen->has_mipmap = ensure_mipmap;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3540,17 +3555,17 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
|
||||
int max_texture_size = job->command_queue->max_texture_size;
|
||||
float scale_x = bounds->size.width / texture->width;
|
||||
float scale_y = bounds->size.height / texture->height;
|
||||
gboolean use_mipmaps;
|
||||
gboolean use_mipmap;
|
||||
|
||||
use_mipmaps = (scale_x * job->scale_x) < 0.5 ||
|
||||
(scale_y * job->scale_y) < 0.5;
|
||||
use_mipmap = (scale_x * job->scale_x) < 0.5 ||
|
||||
(scale_y * job->scale_y) < 0.5;
|
||||
|
||||
if G_LIKELY (texture->width <= max_texture_size &&
|
||||
texture->height <= max_texture_size)
|
||||
{
|
||||
GskGLRenderOffscreen offscreen = {0};
|
||||
|
||||
gsk_gl_render_job_upload_texture (job, texture, use_mipmaps, &offscreen);
|
||||
gsk_gl_render_job_upload_texture (job, texture, use_mipmap, &offscreen);
|
||||
|
||||
g_assert (offscreen.texture_id);
|
||||
g_assert (offscreen.was_offscreen == FALSE);
|
||||
@ -3561,7 +3576,7 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
offscreen.texture_id,
|
||||
use_mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
|
||||
offscreen.has_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
|
||||
GL_LINEAR);
|
||||
gsk_gl_render_job_draw_offscreen (job, bounds, &offscreen);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
@ -3573,7 +3588,7 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
|
||||
GskGLTextureSlice *slices = NULL;
|
||||
guint n_slices = 0;
|
||||
|
||||
gsk_gl_driver_slice_texture (job->driver, texture, use_mipmaps, &slices, &n_slices);
|
||||
gsk_gl_driver_slice_texture (job->driver, texture, use_mipmap, &slices, &n_slices);
|
||||
|
||||
g_assert (slices != NULL);
|
||||
g_assert (n_slices > 0);
|
||||
@ -3597,7 +3612,7 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
slice->texture_id,
|
||||
use_mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
|
||||
use_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
|
||||
GL_LINEAR);
|
||||
|
||||
gsk_gl_render_job_draw_coords (job,
|
||||
|
Loading…
Reference in New Issue
Block a user