mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 06:21:14 +00:00
Merge branch 'cache-scaled-texture' into 'main'
gsk: Cache scaled texture Closes #5642 See merge request GNOME/gtk!5633
This commit is contained in:
commit
bf1a5d99cf
@ -1,18 +1,75 @@
|
|||||||
/* Menu
|
/* Image Scaling
|
||||||
* #Keywords: action, zoom
|
* #Keywords: zoom, scale, filter, action, menu
|
||||||
*
|
|
||||||
* Demonstrates how to add a context menu to a custom widget
|
|
||||||
* and connect it with widget actions.
|
|
||||||
*
|
*
|
||||||
* The custom widget we create here is similar to a GtkPicture,
|
* The custom widget we create here is similar to a GtkPicture,
|
||||||
* but allows setting a zoom level for the displayed paintable.
|
* but allows setting a zoom level and filtering mode for the
|
||||||
|
* displayed paintable.
|
||||||
*
|
*
|
||||||
* Our context menu has items to change the zoom level.
|
* It also demonstrates how to add a context menu to a custom
|
||||||
|
* widget and connect it with widget actions.
|
||||||
|
*
|
||||||
|
* The context menu has items to change the zoom level.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include "demo3widget.h"
|
#include "demo3widget.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
file_opened (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
GFile *file;
|
||||||
|
GError *error = NULL;
|
||||||
|
GdkTexture *texture;
|
||||||
|
|
||||||
|
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
g_print ("%s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture = gdk_texture_new_from_file (file, &error);
|
||||||
|
g_object_unref (file);
|
||||||
|
if (!texture)
|
||||||
|
{
|
||||||
|
g_print ("%s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set (G_OBJECT (data), "texture", texture, NULL);
|
||||||
|
g_object_unref (texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
open_file (GtkWidget *picker,
|
||||||
|
GtkWidget *demo)
|
||||||
|
{
|
||||||
|
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (picker));
|
||||||
|
GtkFileDialog *dialog;
|
||||||
|
GtkFileFilter *filter;
|
||||||
|
GListStore *filters;
|
||||||
|
|
||||||
|
dialog = gtk_file_dialog_new ();
|
||||||
|
|
||||||
|
filter = gtk_file_filter_new ();
|
||||||
|
gtk_file_filter_set_name (filter, "Images");
|
||||||
|
gtk_file_filter_add_pixbuf_formats (filter);
|
||||||
|
filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
|
||||||
|
g_list_store_append (filters, filter);
|
||||||
|
g_object_unref (filter);
|
||||||
|
|
||||||
|
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
|
||||||
|
g_object_unref (filters);
|
||||||
|
|
||||||
|
gtk_file_dialog_open (dialog, parent, NULL, file_opened, demo);
|
||||||
|
|
||||||
|
g_object_unref (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
do_menu (GtkWidget *do_widget)
|
do_menu (GtkWidget *do_widget)
|
||||||
@ -27,9 +84,10 @@ do_menu (GtkWidget *do_widget)
|
|||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
GtkWidget *scale;
|
GtkWidget *scale;
|
||||||
GtkWidget *dropdown;
|
GtkWidget *dropdown;
|
||||||
|
GtkWidget *button;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new ();
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Menu");
|
gtk_window_set_title (GTK_WINDOW (window), "Image Scaling");
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||||
gtk_window_set_display (GTK_WINDOW (window),
|
gtk_window_set_display (GTK_WINDOW (window),
|
||||||
gtk_widget_get_display (do_widget));
|
gtk_widget_get_display (do_widget));
|
||||||
@ -48,12 +106,19 @@ do_menu (GtkWidget *do_widget)
|
|||||||
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
gtk_box_append (GTK_BOX (box), box2);
|
gtk_box_append (GTK_BOX (box), box2);
|
||||||
|
|
||||||
|
button = gtk_button_new_from_icon_name ("document-open-symbolic");
|
||||||
|
gtk_widget_set_tooltip_text (button, "Open File");
|
||||||
|
g_signal_connect (button, "clicked", G_CALLBACK (open_file), widget);
|
||||||
|
gtk_box_append (GTK_BOX (box2), button);
|
||||||
|
|
||||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
|
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
|
||||||
|
gtk_widget_set_tooltip_text (scale, "Zoom");
|
||||||
gtk_range_set_value (GTK_RANGE (scale), 1.0);
|
gtk_range_set_value (GTK_RANGE (scale), 1.0);
|
||||||
gtk_widget_set_hexpand (scale, TRUE);
|
gtk_widget_set_hexpand (scale, TRUE);
|
||||||
gtk_box_append (GTK_BOX (box2), scale);
|
gtk_box_append (GTK_BOX (box2), scale);
|
||||||
|
|
||||||
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
|
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
|
||||||
|
gtk_widget_set_tooltip_text (dropdown, "Filter");
|
||||||
gtk_box_append (GTK_BOX (box2), dropdown);
|
gtk_box_append (GTK_BOX (box2), dropdown);
|
||||||
|
|
||||||
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
|
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
|
||||||
|
@ -3640,6 +3640,7 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
|
|||||||
guint prev_fbo;
|
guint prev_fbo;
|
||||||
guint texture_id;
|
guint texture_id;
|
||||||
float u0, u1, v0, v1;
|
float u0, u1, v0, v1;
|
||||||
|
GskTextureKey key;
|
||||||
|
|
||||||
gsk_gl_render_job_untransform_bounds (job, &job->current_clip->rect.bounds, &clip_rect);
|
gsk_gl_render_job_untransform_bounds (job, &job->current_clip->rect.bounds, &clip_rect);
|
||||||
if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect))
|
if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect))
|
||||||
@ -3652,6 +3653,17 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key.pointer = node;
|
||||||
|
key.pointer_is_child = TRUE;
|
||||||
|
key.parent_rect = clip_rect;
|
||||||
|
key.scale_x = 1.;
|
||||||
|
key.scale_y = 1.;
|
||||||
|
key.filter = min_filter;
|
||||||
|
|
||||||
|
texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
|
||||||
|
if (texture_id != 0)
|
||||||
|
goto render_texture;
|
||||||
|
|
||||||
viewport = GRAPHENE_RECT_INIT (0, 0,
|
viewport = GRAPHENE_RECT_INIT (0, 0,
|
||||||
clip_rect.size.width,
|
clip_rect.size.width,
|
||||||
clip_rect.size.height);
|
clip_rect.size.height);
|
||||||
@ -3707,6 +3719,9 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
|
|||||||
|
|
||||||
texture_id = gsk_gl_driver_release_render_target (job->driver, render_target, FALSE);
|
texture_id = gsk_gl_driver_release_render_target (job->driver, render_target, FALSE);
|
||||||
|
|
||||||
|
gsk_gl_driver_cache_texture (job->driver, &key, texture_id);
|
||||||
|
|
||||||
|
render_texture:
|
||||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
|
||||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||||
UNIFORM_SHARED_SOURCE, 0,
|
UNIFORM_SHARED_SOURCE, 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user