forked from AuroraMiddleware/gtk
Moved GtkSizeRequest cache to GtkWidget->priv
Now that we have a private data installed directly on the GtkWidget instance it makes no sense to cache the size requests on widget qdata. This change will generally make GTK+ memory less fragmented as well as significantly speed up the size request process.
This commit is contained in:
parent
f76fddb8a7
commit
843be48572
@ -114,6 +114,28 @@ gboolean _gtk_fnmatch (const char *pattern,
|
|||||||
#define GTK_DEFAULT_ACCEL_MOD_MASK GDK_META_MASK
|
#define GTK_DEFAULT_ACCEL_MOD_MASK GDK_META_MASK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* With GtkSizeRequest, a widget may be requested
|
||||||
|
* its width for 2 or maximum 3 heights in one resize
|
||||||
|
*/
|
||||||
|
#define GTK_SIZE_REQUEST_CACHED_SIZES 3
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
guint age;
|
||||||
|
gint for_size;
|
||||||
|
gint minimum_size;
|
||||||
|
gint natural_size;
|
||||||
|
} SizeRequest;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SizeRequest widths[GTK_SIZE_REQUEST_CACHED_SIZES];
|
||||||
|
SizeRequest heights[GTK_SIZE_REQUEST_CACHED_SIZES];
|
||||||
|
guint8 cached_width_age;
|
||||||
|
guint8 cached_height_age;
|
||||||
|
} SizeRequestCache;
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GTK_PRIVATE_H__ */
|
#endif /* __GTK_PRIVATE_H__ */
|
||||||
|
@ -98,34 +98,10 @@
|
|||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
|
|
||||||
/* With GtkSizeRequest, a widget may be requested
|
|
||||||
* its width for 2 or maximum 3 heights in one resize
|
|
||||||
*/
|
|
||||||
#define N_CACHED_SIZES 3
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
guint age;
|
|
||||||
gint for_size;
|
|
||||||
gint minimum_size;
|
|
||||||
gint natural_size;
|
|
||||||
} SizeRequest;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
SizeRequest widths[N_CACHED_SIZES];
|
|
||||||
SizeRequest heights[N_CACHED_SIZES];
|
|
||||||
guint8 cached_width_age;
|
|
||||||
guint8 cached_height_age;
|
|
||||||
} SizeRequestCache;
|
|
||||||
|
|
||||||
static GQuark quark_cache = 0;
|
|
||||||
|
|
||||||
|
|
||||||
typedef GtkSizeRequestIface GtkSizeRequestInterface;
|
typedef GtkSizeRequestIface GtkSizeRequestInterface;
|
||||||
G_DEFINE_INTERFACE_WITH_CODE (GtkSizeRequest,
|
G_DEFINE_INTERFACE (GtkSizeRequest,
|
||||||
gtk_size_request,
|
gtk_size_request,
|
||||||
GTK_TYPE_WIDGET,
|
GTK_TYPE_WIDGET);
|
||||||
quark_cache = g_quark_from_static_string ("gtk-size-request-cache"));
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -149,7 +125,7 @@ get_cached_size (gint for_size,
|
|||||||
|
|
||||||
*result = &cached_sizes[0];
|
*result = &cached_sizes[0];
|
||||||
|
|
||||||
for (i = 0; i < N_CACHED_SIZES; i++)
|
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES; i++)
|
||||||
{
|
{
|
||||||
SizeRequest *cs;
|
SizeRequest *cs;
|
||||||
|
|
||||||
@ -169,33 +145,6 @@ get_cached_size (gint for_size,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
destroy_cache (SizeRequestCache *cache)
|
|
||||||
{
|
|
||||||
g_slice_free (SizeRequestCache, cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
static SizeRequestCache *
|
|
||||||
get_cache (GtkSizeRequest *widget,
|
|
||||||
gboolean create)
|
|
||||||
{
|
|
||||||
SizeRequestCache *cache;
|
|
||||||
|
|
||||||
cache = g_object_get_qdata (G_OBJECT (widget), quark_cache);
|
|
||||||
if (!cache && create)
|
|
||||||
{
|
|
||||||
cache = g_slice_new0 (SizeRequestCache);
|
|
||||||
|
|
||||||
cache->cached_width_age = 1;
|
|
||||||
cache->cached_height_age = 1;
|
|
||||||
|
|
||||||
g_object_set_qdata_full (G_OBJECT (widget), quark_cache, cache,
|
|
||||||
(GDestroyNotify)destroy_cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_size_request (GtkWidget *widget,
|
do_size_request (GtkWidget *widget,
|
||||||
GtkRequisition *requisition)
|
GtkRequisition *requisition)
|
||||||
@ -222,7 +171,7 @@ compute_size_for_orientation (GtkSizeRequest *request,
|
|||||||
g_return_if_fail (minimum_size != NULL || natural_size != NULL);
|
g_return_if_fail (minimum_size != NULL || natural_size != NULL);
|
||||||
|
|
||||||
widget = GTK_WIDGET (request);
|
widget = GTK_WIDGET (request);
|
||||||
cache = get_cache (request, TRUE);
|
cache = _gtk_widget_peek_request_cache (widget);
|
||||||
|
|
||||||
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
|
||||||
{
|
{
|
||||||
@ -232,7 +181,7 @@ compute_size_for_orientation (GtkSizeRequest *request,
|
|||||||
found_in_cache = get_cached_size (for_size, cache->widths, &cached_size);
|
found_in_cache = get_cached_size (for_size, cache->widths, &cached_size);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset (cache->widths, 0, N_CACHED_SIZES * sizeof (SizeRequest));
|
memset (cache->widths, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest));
|
||||||
cache->cached_width_age = 1;
|
cache->cached_width_age = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +193,7 @@ compute_size_for_orientation (GtkSizeRequest *request,
|
|||||||
found_in_cache = get_cached_size (for_size, cache->heights, &cached_size);
|
found_in_cache = get_cached_size (for_size, cache->heights, &cached_size);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset (cache->heights, 0, N_CACHED_SIZES * sizeof (SizeRequest));
|
memset (cache->heights, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest));
|
||||||
cache->cached_height_age = 1;
|
cache->cached_height_age = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,6 +168,9 @@ struct _GtkWidgetPrivate
|
|||||||
*/
|
*/
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
|
|
||||||
|
/* The widget's requested sizes */
|
||||||
|
SizeRequestCache requests;
|
||||||
|
|
||||||
/* The widget's window or its parent window if it does
|
/* The widget's window or its parent window if it does
|
||||||
* not have a window. (Which will be indicated by the
|
* not have a window. (Which will be indicated by the
|
||||||
* GTK_NO_WINDOW flag being set).
|
* GTK_NO_WINDOW flag being set).
|
||||||
@ -9071,6 +9074,21 @@ _gtk_widget_peek_colormap (void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _gtk_widget_peek_request_cache:
|
||||||
|
*
|
||||||
|
* Returns the address of the widget's request cache (strictly for
|
||||||
|
* internal use in gtksizerequest.c)
|
||||||
|
*
|
||||||
|
* Return value: the address of @widget's size request cache.
|
||||||
|
**/
|
||||||
|
gpointer
|
||||||
|
_gtk_widget_peek_request_cache (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
/* Don't bother slowing things down with the return_if_fail guards here */
|
||||||
|
return &widget->priv->requests;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _gtk_widget_set_device_window:
|
* _gtk_widget_set_device_window:
|
||||||
* @widget: a #GtkWidget.
|
* @widget: a #GtkWidget.
|
||||||
|
@ -941,6 +941,8 @@ void _gtk_widget_synthesize_crossing (GtkWidget *from,
|
|||||||
|
|
||||||
GdkColormap* _gtk_widget_peek_colormap (void);
|
GdkColormap* _gtk_widget_peek_colormap (void);
|
||||||
|
|
||||||
|
gpointer _gtk_widget_peek_request_cache (GtkWidget *widget);
|
||||||
|
|
||||||
void _gtk_widget_buildable_finish_accelerator (GtkWidget *widget,
|
void _gtk_widget_buildable_finish_accelerator (GtkWidget *widget,
|
||||||
GtkWidget *toplevel,
|
GtkWidget *toplevel,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
Loading…
Reference in New Issue
Block a user