StTextureCache: add api to load image to cairo surface
Loading a pixbuf in a way that cairo can use it is a pretty involved process that involves a lot of code, and pixel fiddling. This commit adds the mechanism to StTextureCache so we can reuse the existing pixbuf handling code there, and also get caching. https://bugzilla.gnome.org/show_bug.cgi?id=636976
This commit is contained in:
parent
a7fa7d748d
commit
f7ab90b93b
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#define CACHE_PREFIX_GICON "gicon:"
|
#define CACHE_PREFIX_GICON "gicon:"
|
||||||
#define CACHE_PREFIX_URI "uri:"
|
#define CACHE_PREFIX_URI "uri:"
|
||||||
|
#define CACHE_PREFIX_URI_FOR_CAIRO "uri-for-cairo:"
|
||||||
#define CACHE_PREFIX_THUMBNAIL_URI "thumbnail-uri:"
|
#define CACHE_PREFIX_THUMBNAIL_URI "thumbnail-uri:"
|
||||||
#define CACHE_PREFIX_RAW_CHECKSUM "raw-checksum:"
|
#define CACHE_PREFIX_RAW_CHECKSUM "raw-checksum:"
|
||||||
#define CACHE_PREFIX_COMPRESSED_CHECKSUM "compressed-checksum:"
|
#define CACHE_PREFIX_COMPRESSED_CHECKSUM "compressed-checksum:"
|
||||||
@ -798,6 +799,27 @@ pixbuf_to_cogl_handle (GdkPixbuf *pixbuf)
|
|||||||
gdk_pixbuf_get_pixels (pixbuf));
|
gdk_pixbuf_get_pixels (pixbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
|
||||||
|
{
|
||||||
|
cairo_surface_t *dummy_surface;
|
||||||
|
cairo_pattern_t *pattern;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
|
||||||
|
|
||||||
|
cr = cairo_create (dummy_surface);
|
||||||
|
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||||
|
pattern = cairo_get_source (cr);
|
||||||
|
cairo_pattern_get_surface (pattern, &surface);
|
||||||
|
cairo_surface_reference (surface);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
cairo_surface_destroy (dummy_surface);
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
static GdkPixbuf *
|
static GdkPixbuf *
|
||||||
load_pixbuf_fallback(AsyncTextureLoadData *data)
|
load_pixbuf_fallback(AsyncTextureLoadData *data)
|
||||||
{
|
{
|
||||||
@ -1504,6 +1526,45 @@ out:
|
|||||||
return texdata;
|
return texdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
st_texture_cache_load_uri_sync_to_cairo_surface (StTextureCache *cache,
|
||||||
|
StTextureCachePolicy policy,
|
||||||
|
const gchar *uri,
|
||||||
|
int available_width,
|
||||||
|
int available_height,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
char *key;
|
||||||
|
|
||||||
|
key = g_strconcat (CACHE_PREFIX_URI_FOR_CAIRO, uri, NULL);
|
||||||
|
|
||||||
|
surface = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
||||||
|
|
||||||
|
if (surface == NULL)
|
||||||
|
{
|
||||||
|
pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, error);
|
||||||
|
if (!pixbuf)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
surface = pixbuf_to_cairo_surface (pixbuf);
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
|
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
|
||||||
|
{
|
||||||
|
cairo_surface_reference (surface);
|
||||||
|
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cairo_surface_reference (surface);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_free (key);
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* st_texture_cache_load_uri_sync:
|
* st_texture_cache_load_uri_sync:
|
||||||
*
|
*
|
||||||
@ -1582,6 +1643,43 @@ st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_texture_cache_load_file_to_cairo_surface:
|
||||||
|
* @cache: A #StTextureCache
|
||||||
|
* @file_path: Path to a file in supported image format
|
||||||
|
*
|
||||||
|
* This function synchronously loads the given file path
|
||||||
|
* into a cairo surface. On error, a warning is emitted
|
||||||
|
* and %NULL is returned.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): a new #cairo_surface_t *
|
||||||
|
*/
|
||||||
|
cairo_surface_t *
|
||||||
|
st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
|
||||||
|
const gchar *file_path)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
GFile *file;
|
||||||
|
char *uri;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
file = g_file_new_for_path (file_path);
|
||||||
|
uri = g_file_get_uri (file);
|
||||||
|
|
||||||
|
surface = st_texture_cache_load_uri_sync_to_cairo_surface (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
|
||||||
|
uri, -1, -1, &error);
|
||||||
|
g_object_unref (file);
|
||||||
|
g_free (uri);
|
||||||
|
|
||||||
|
if (surface == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to load %s: %s", file_path, error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* st_texture_cache_load_file_simple:
|
* st_texture_cache_load_file_simple:
|
||||||
* @cache: A #StTextureCache
|
* @cache: A #StTextureCache
|
||||||
|
@ -119,6 +119,9 @@ ClutterActor *st_texture_cache_load_uri_sync (StTextureCache *cache,
|
|||||||
CoglHandle st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
|
CoglHandle st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
|
||||||
const gchar *file_path);
|
const gchar *file_path);
|
||||||
|
|
||||||
|
cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
|
||||||
|
const gchar *file_path);
|
||||||
|
|
||||||
ClutterActor *st_texture_cache_load_file_simple (StTextureCache *cache,
|
ClutterActor *st_texture_cache_load_file_simple (StTextureCache *cache,
|
||||||
const gchar *file_path);
|
const gchar *file_path);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user