summaryrefslogtreecommitdiffstats
path: root/gfx/cairo/cairo/src/cairo-cogl-gradient.c
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/cairo/cairo/src/cairo-cogl-gradient.c')
-rw-r--r--gfx/cairo/cairo/src/cairo-cogl-gradient.c678
1 files changed, 0 insertions, 678 deletions
diff --git a/gfx/cairo/cairo/src/cairo-cogl-gradient.c b/gfx/cairo/cairo/src/cairo-cogl-gradient.c
deleted file mode 100644
index cdb4cae82d..0000000000
--- a/gfx/cairo/cairo/src/cairo-cogl-gradient.c
+++ /dev/null
@@ -1,678 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2011 Intel Corporation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.og/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * Contributor(s):
- * Robert Bragg <robert@linux.intel.com>
- */
-//#include "cairoint.h"
-
-#include "cairo-cogl-private.h"
-#include "cairo-cogl-gradient-private.h"
-#include "cairo-image-surface-private.h"
-
-#include <cogl/cogl2-experimental.h>
-#include <glib.h>
-
-//#define DUMP_GRADIENTS_TO_PNG
-
-static unsigned long
-_cairo_cogl_linear_gradient_hash (unsigned int n_stops,
- const cairo_gradient_stop_t *stops)
-{
- return _cairo_hash_bytes (n_stops, stops,
- sizeof (cairo_gradient_stop_t) * n_stops);
-}
-
-static cairo_cogl_linear_gradient_t *
-_cairo_cogl_linear_gradient_lookup (cairo_cogl_device_t *ctx,
- unsigned long hash,
- unsigned int n_stops,
- const cairo_gradient_stop_t *stops)
-{
- cairo_cogl_linear_gradient_t lookup;
-
- lookup.cache_entry.hash = hash,
- lookup.n_stops = n_stops;
- lookup.stops = stops;
-
- return _cairo_cache_lookup (&ctx->linear_cache, &lookup.cache_entry);
-}
-
-cairo_bool_t
-_cairo_cogl_linear_gradient_equal (const void *key_a, const void *key_b)
-{
- const cairo_cogl_linear_gradient_t *a = key_a;
- const cairo_cogl_linear_gradient_t *b = key_b;
-
- if (a->n_stops != b->n_stops)
- return FALSE;
-
- return memcmp (a->stops, b->stops, a->n_stops * sizeof (cairo_gradient_stop_t)) == 0;
-}
-
-cairo_cogl_linear_gradient_t *
-_cairo_cogl_linear_gradient_reference (cairo_cogl_linear_gradient_t *gradient)
-{
- assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count));
-
- _cairo_reference_count_inc (&gradient->ref_count);
-
- return gradient;
-}
-
-void
-_cairo_cogl_linear_gradient_destroy (cairo_cogl_linear_gradient_t *gradient)
-{
- GList *l;
-
- assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count));
-
- if (! _cairo_reference_count_dec_and_test (&gradient->ref_count))
- return;
-
- for (l = gradient->textures; l; l = l->next) {
- cairo_cogl_linear_texture_entry_t *entry = l->data;
- cogl_object_unref (entry->texture);
- free (entry);
- }
- g_list_free (gradient->textures);
-
- free (gradient);
-}
-
-static int
-_cairo_cogl_util_next_p2 (int a)
-{
- int rval = 1;
-
- while (rval < a)
- rval <<= 1;
-
- return rval;
-}
-
-static float
-get_max_color_component_range (const cairo_color_stop_t *color0,
- const cairo_color_stop_t *color1)
-{
- float range;
- float max = 0;
-
- range = fabs (color0->red - color1->red);
- max = MAX (range, max);
- range = fabs (color0->green - color1->green);
- max = MAX (range, max);
- range = fabs (color0->blue - color1->blue);
- max = MAX (range, max);
- range = fabs (color0->alpha - color1->alpha);
- max = MAX (range, max);
-
- return max;
-}
-
-static int
-_cairo_cogl_linear_gradient_width_for_stops (cairo_extend_t extend,
- unsigned int n_stops,
- const cairo_gradient_stop_t *stops)
-{
- unsigned int n;
- float max_texels_per_unit_offset = 0;
- float total_offset_range;
-
- /* Find the stop pair demanding the most precision because we are
- * interpolating the largest color-component range.
- *
- * From that we can define the relative sizes of all the other
- * stop pairs within our texture and thus the overall size.
- *
- * To determine the maximum number of texels for a given gap we
- * look at the range of colors we are expected to interpolate (so
- * long as the stop offsets are not degenerate) and we simply
- * assume we want one texel for each unique color value possible
- * for a one byte-per-component representation.
- * XXX: maybe this is overkill and just allowing 128 levels
- * instead of 256 would be enough and then we'd rely on the
- * bilinear filtering to give the full range.
- *
- * XXX: potentially we could try and map offsets to pixels to come
- * up with a more precise mapping, but we are aiming to cache
- * the gradients so we can't make assumptions about how it will be
- * scaled in the future.
- */
- for (n = 1; n < n_stops; n++) {
- float color_range;
- float offset_range;
- float texels;
- float texels_per_unit_offset;
-
- /* note: degenerate stops don't need to be represented in the
- * texture but we want to be sure that solid gaps get at least
- * one texel and all other gaps get at least 2 texels.
- */
-
- if (stops[n].offset == stops[n-1].offset)
- continue;
-
- color_range = get_max_color_component_range (&stops[n].color, &stops[n-1].color);
- if (color_range == 0)
- texels = 1;
- else
- texels = MAX (2, 256.0f * color_range);
-
- /* So how many texels would we need to map over the full [0,1]
- * gradient range so this gap would have enough texels? ... */
- offset_range = stops[n].offset - stops[n - 1].offset;
- texels_per_unit_offset = texels / offset_range;
-
- if (texels_per_unit_offset > max_texels_per_unit_offset)
- max_texels_per_unit_offset = texels_per_unit_offset;
- }
-
- total_offset_range = fabs (stops[n_stops - 1].offset - stops[0].offset);
- return max_texels_per_unit_offset * total_offset_range;
-}
-
-/* Aim to create gradient textures without an alpha component so we can avoid
- * needing to use blending... */
-static CoglTextureComponents
-_cairo_cogl_linear_gradient_components_for_stops (cairo_extend_t extend,
- unsigned int n_stops,
- const cairo_gradient_stop_t *stops)
-{
- unsigned int n;
-
- /* We have to add extra transparent texels to the end of the gradient to
- * handle CAIRO_EXTEND_NONE... */
- if (extend == CAIRO_EXTEND_NONE)
- return COGL_TEXTURE_COMPONENTS_RGBA;
-
- for (n = 1; n < n_stops; n++) {
- if (stops[n].color.alpha != 1.0)
- return COGL_TEXTURE_COMPONENTS_RGBA;
- }
-
- return COGL_TEXTURE_COMPONENTS_RGBA;
-}
-
-static cairo_cogl_gradient_compatibility_t
-_cairo_cogl_compatibility_from_extend_mode (cairo_extend_t extend_mode)
-{
- switch (extend_mode)
- {
- case CAIRO_EXTEND_NONE:
- return CAIRO_COGL_GRADIENT_CAN_EXTEND_NONE;
- case CAIRO_EXTEND_PAD:
- return CAIRO_COGL_GRADIENT_CAN_EXTEND_PAD;
- case CAIRO_EXTEND_REPEAT:
- return CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT;
- case CAIRO_EXTEND_REFLECT:
- return CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT;
- }
-
- assert (0); /* not reached */
- return CAIRO_EXTEND_NONE;
-}
-
-cairo_cogl_linear_texture_entry_t *
-_cairo_cogl_linear_gradient_texture_for_extend (cairo_cogl_linear_gradient_t *gradient,
- cairo_extend_t extend_mode)
-{
- GList *l;
- cairo_cogl_gradient_compatibility_t compatibility =
- _cairo_cogl_compatibility_from_extend_mode (extend_mode);
- for (l = gradient->textures; l; l = l->next) {
- cairo_cogl_linear_texture_entry_t *entry = l->data;
- if (entry->compatibility & compatibility)
- return entry;
- }
- return NULL;
-}
-
-static void
-color_stop_lerp (const cairo_color_stop_t *c0,
- const cairo_color_stop_t *c1,
- float factor,
- cairo_color_stop_t *dest)
-{
- /* NB: we always ignore the short members in this file so we don't need to
- * worry about initializing them here. */
- dest->red = c0->red * (1.0f-factor) + c1->red * factor;
- dest->green = c0->green * (1.0f-factor) + c1->green * factor;
- dest->blue = c0->blue * (1.0f-factor) + c1->blue * factor;
- dest->alpha = c0->alpha * (1.0f-factor) + c1->alpha * factor;
-}
-
-static size_t
-_cairo_cogl_linear_gradient_size (cairo_cogl_linear_gradient_t *gradient)
-{
- GList *l;
- size_t size = 0;
- for (l = gradient->textures; l; l = l->next) {
- cairo_cogl_linear_texture_entry_t *entry = l->data;
- size += cogl_texture_get_width (entry->texture) * 4;
- }
- return size;
-}
-
-static void
-emit_stop (CoglVertexP2C4 **position,
- float left,
- float right,
- const cairo_color_stop_t *left_color,
- const cairo_color_stop_t *right_color)
-{
- CoglVertexP2C4 *p = *position;
-
- guint8 lr = left_color->red * 255;
- guint8 lg = left_color->green * 255;
- guint8 lb = left_color->blue * 255;
- guint8 la = left_color->alpha * 255;
-
- guint8 rr = right_color->red * 255;
- guint8 rg = right_color->green * 255;
- guint8 rb = right_color->blue * 255;
- guint8 ra = right_color->alpha * 255;
-
- p[0].x = left;
- p[0].y = 0;
- p[0].r = lr; p[0].g = lg; p[0].b = lb; p[0].a = la;
- p[1].x = left;
- p[1].y = 1;
- p[1].r = lr; p[1].g = lg; p[1].b = lb; p[1].a = la;
- p[2].x = right;
- p[2].y = 1;
- p[2].r = rr; p[2].g = rg; p[2].b = rb; p[2].a = ra;
-
- p[3].x = left;
- p[3].y = 0;
- p[3].r = lr; p[3].g = lg; p[3].b = lb; p[3].a = la;
- p[4].x = right;
- p[4].y = 1;
- p[4].r = rr; p[4].g = rg; p[4].b = rb; p[4].a = ra;
- p[5].x = right;
- p[5].y = 0;
- p[5].r = rr; p[5].g = rg; p[5].b = rb; p[5].a = ra;
-
- *position = &p[6];
-}
-
-#ifdef DUMP_GRADIENTS_TO_PNG
-static void
-dump_gradient_to_png (CoglTexture *texture)
-{
- cairo_image_surface_t *image = (cairo_image_surface_t *)
- cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- cogl_texture_get_width (texture),
- cogl_texture_get_height (texture));
- CoglPixelFormat format;
- static int gradient_id = 0;
- char *gradient_name;
-
- if (image->base.status)
- return;
-
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
-#else
- format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
-#endif
- cogl_texture_get_data (texture,
- format,
- 0,
- image->data);
- gradient_name = g_strdup_printf ("./gradient%d.png", gradient_id++);
- g_print ("writing gradient: %s\n", gradient_name);
- cairo_surface_write_to_png ((cairo_surface_t *)image, gradient_name);
- g_free (gradient_name);
-}
-#endif
-
-cairo_int_status_t
-_cairo_cogl_get_linear_gradient (cairo_cogl_device_t *device,
- cairo_extend_t extend_mode,
- int n_stops,
- const cairo_gradient_stop_t *stops,
- const cairo_bool_t need_mirrored_gradient,
- cairo_cogl_linear_gradient_t **gradient_out)
-{
- unsigned long hash;
- cairo_cogl_linear_gradient_t *gradient;
- cairo_cogl_linear_texture_entry_t *entry;
- cairo_gradient_stop_t *internal_stops;
- int stop_offset;
- int n_internal_stops;
- int n;
- cairo_cogl_gradient_compatibility_t compatibilities;
- int width;
- int tex_width;
- int left_padding = 0;
- cairo_color_stop_t left_padding_color;
- int right_padding = 0;
- cairo_color_stop_t right_padding_color;
- CoglTextureComponents components;
- CoglTexture2D *tex;
- int un_padded_width;
- CoglFramebuffer *offscreen = NULL;
- cairo_int_status_t status;
- int n_quads;
- int n_vertices;
- float prev;
- float right;
- CoglVertexP2C4 *vertices;
- CoglVertexP2C4 *p;
- CoglPrimitive *prim;
- CoglPipeline *pipeline;
-
- hash = _cairo_cogl_linear_gradient_hash (n_stops, stops);
-
- gradient = _cairo_cogl_linear_gradient_lookup (device, hash, n_stops, stops);
- if (gradient) {
- cairo_cogl_linear_texture_entry_t *entry =
- _cairo_cogl_linear_gradient_texture_for_extend (gradient, extend_mode);
- if (entry) {
- *gradient_out = _cairo_cogl_linear_gradient_reference (gradient);
- return CAIRO_INT_STATUS_SUCCESS;
- }
- }
-
- if (!gradient) {
- gradient = _cairo_malloc (sizeof (cairo_cogl_linear_gradient_t) +
- sizeof (cairo_gradient_stop_t) * (n_stops - 1));
- if (!gradient)
- return CAIRO_INT_STATUS_NO_MEMORY;
-
- CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 1);
- /* NB: we update the cache_entry size at the end before
- * [re]adding it to the cache. */
- gradient->cache_entry.hash = hash;
- gradient->textures = NULL;
- gradient->n_stops = n_stops;
- gradient->stops = gradient->stops_embedded;
- memcpy (gradient->stops_embedded, stops, sizeof (cairo_gradient_stop_t) * n_stops);
- } else {
- _cairo_cogl_linear_gradient_reference (gradient);
- }
-
- entry = _cairo_malloc (sizeof (cairo_cogl_linear_texture_entry_t));
- if (unlikely (!entry)) {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto BAIL;
- }
-
- compatibilities = _cairo_cogl_compatibility_from_extend_mode (extend_mode);
-
- n_internal_stops = n_stops;
- stop_offset = 0;
-
- /* We really need stops covering the full [0,1] range for repeat/reflect
- * if we want to use sampler REPEAT/MIRROR wrap modes so we may need
- * to add some extra stops... */
- if (extend_mode == CAIRO_EXTEND_REPEAT || extend_mode == CAIRO_EXTEND_REFLECT)
- {
- /* If we don't need any extra stops then actually the texture
- * will be shareable for repeat and reflect... */
- compatibilities = (CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT |
- CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT);
-
- if (stops[0].offset != 0) {
- n_internal_stops++;
- stop_offset++;
- }
-
- if (stops[n_stops - 1].offset != 1)
- n_internal_stops++;
- }
-
- internal_stops = alloca (n_internal_stops * sizeof (cairo_gradient_stop_t));
- memcpy (&internal_stops[stop_offset], stops, sizeof (cairo_gradient_stop_t) * n_stops);
-
- /* cairo_color_stop_t values are all unpremultiplied but we need to
- * interpolate premultiplied colors so we premultiply all the double
- * components now. (skipping any extra stops added for repeat/reflect)
- *
- * Another thing to note is that by premultiplying the colors
- * early we'll also reduce the range of colors to interpolate
- * which can result in smaller gradient textures.
- */
- for (n = stop_offset; n < n_stops; n++) {
- cairo_color_stop_t *color = &internal_stops[n].color;
- color->red *= color->alpha;
- color->green *= color->alpha;
- color->blue *= color->alpha;
- }
-
- if (n_internal_stops != n_stops)
- {
- if (extend_mode == CAIRO_EXTEND_REPEAT) {
- compatibilities &= ~CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT;
- if (stops[0].offset != 0) {
- /* what's the wrap-around distance between the user's end-stops? */
- double dx = (1.0 - stops[n_stops - 1].offset) + stops[0].offset;
- internal_stops[0].offset = 0;
- color_stop_lerp (&stops[0].color,
- &stops[n_stops - 1].color,
- stops[0].offset / dx,
- &internal_stops[0].color);
- }
- if (stops[n_stops - 1].offset != 1) {
- internal_stops[n_internal_stops - 1].offset = 1;
- internal_stops[n_internal_stops - 1].color = internal_stops[0].color;
- }
- } else if (extend_mode == CAIRO_EXTEND_REFLECT) {
- compatibilities &= ~CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT;
- if (stops[0].offset != 0) {
- internal_stops[0].offset = 0;
- internal_stops[0].color = stops[n_stops - 1].color;
- }
- if (stops[n_stops - 1].offset != 1) {
- internal_stops[n_internal_stops - 1].offset = 1;
- internal_stops[n_internal_stops - 1].color = stops[0].color;
- }
- }
- }
-
- stops = internal_stops;
- n_stops = n_internal_stops;
-
- width = _cairo_cogl_linear_gradient_width_for_stops (extend_mode, n_stops, stops);
-
- if (extend_mode == CAIRO_EXTEND_PAD) {
-
- /* Here we need to guarantee that the edge texels of our
- * texture correspond to the desired padding color so we
- * can use CLAMP_TO_EDGE.
- *
- * For short stop-gaps and especially for degenerate stops
- * it's possible that without special consideration the
- * user's end stop colors would not be present in our final
- * texture.
- *
- * To handle this we forcibly add two extra padding texels
- * at the edges which extend beyond the [0,1] range of the
- * gradient itself and we will later report a translate and
- * scale transform to compensate for this.
- */
-
- /* XXX: If we consider generating a mipmap for our 1d texture
- * at some point then we also need to consider how much
- * padding to add to be sure lower mipmap levels still have
- * the desired edge color (as opposed to a linear blend with
- * other colors of the gradient).
- */
-
- left_padding = 1;
- left_padding_color = stops[0].color;
- right_padding = 1;
- right_padding_color = stops[n_stops - 1].color;
- } else if (extend_mode == CAIRO_EXTEND_NONE) {
- /* We handle EXTEND_NONE by adding two extra, transparent, texels at
- * the ends of the texture and use CLAMP_TO_EDGE.
- *
- * We add a scale and translate transform so to account for our texels
- * extending beyond the [0,1] range. */
-
- left_padding = 1;
- left_padding_color.red = 0;
- left_padding_color.green = 0;
- left_padding_color.blue = 0;
- left_padding_color.alpha = 0;
- right_padding = 1;
- right_padding_color = left_padding_color;
- }
-
- /* If we still have stops that don't cover the full [0,1] range
- * then we need to define a texture-coordinate scale + translate
- * transform to account for that... */
- if (stops[n_stops - 1].offset - stops[0].offset < 1) {
- float range = stops[n_stops - 1].offset - stops[0].offset;
- entry->scale_x = 1.0 / range;
- entry->translate_x = -(stops[0].offset * entry->scale_x);
- }
-
- width += left_padding + right_padding;
-
- width = _cairo_cogl_util_next_p2 (width);
- width = MIN (4096, width); /* lets not go too stupidly big! */
-
- if (!device->has_npots)
- width = pow (2, ceil (log2 (width)));
-
- if (need_mirrored_gradient)
- tex_width = width * 2;
- else
- tex_width = width;
-
- components = _cairo_cogl_linear_gradient_components_for_stops (extend_mode, n_stops, stops);
-
- do {
- tex = cogl_texture_2d_new_with_size (device->cogl_context,
- tex_width, 1);
- } while (tex == NULL && width >> 1 && tex_width >> 1);
-
- if (unlikely (!tex)) {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto BAIL;
- }
-
- cogl_texture_set_components (tex, components);
-
- entry->texture = tex;
- entry->compatibility = compatibilities;
-
- un_padded_width = width - left_padding - right_padding;
-
- /* XXX: only when we know the final texture width can we calculate the
- * scale and translate factors needed to account for padding... */
- if (un_padded_width != width)
- entry->scale_x *= (float)un_padded_width / (float)width;
- if (left_padding)
- entry->translate_x += (entry->scale_x / (float)un_padded_width) * (float)left_padding;
-
- offscreen = cogl_offscreen_new_with_texture (tex);
- cogl_framebuffer_orthographic (offscreen, 0, 0,
- tex_width, 1,
- -1, 100);
- cogl_framebuffer_clear4f (offscreen,
- COGL_BUFFER_BIT_COLOR,
- 0, 0, 0, 0);
-
- n_quads = n_stops - 1 + !!left_padding + !!right_padding;
- n_vertices = 6 * n_quads;
- vertices = _cairo_malloc_ab (n_vertices, sizeof (CoglVertexP2C4));
- if (unlikely (!vertices)) {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto BAIL;
- }
-
- p = vertices;
- if (left_padding)
- emit_stop (&p, 0, left_padding, &left_padding_color, &left_padding_color);
- prev = (float)left_padding;
- for (n = 1; n < n_stops; n++) {
- right = (float)left_padding + (float)un_padded_width * stops[n].offset;
- emit_stop (&p, prev, right, &stops[n-1].color, &stops[n].color);
- prev = right;
- }
- if (right_padding)
- emit_stop (&p, prev, width, &right_padding_color, &right_padding_color);
-
- prim = cogl_primitive_new_p2c4 (device->cogl_context,
- COGL_VERTICES_MODE_TRIANGLES,
- n_vertices,
- vertices);
- free (vertices);
- pipeline = cogl_pipeline_new (device->cogl_context);
- cogl_primitive_draw (prim, offscreen, pipeline);
-
- if (need_mirrored_gradient) {
- /* In order to use a reflected gradient on hardware that
- * doesn't have a mirrored repeating texture wrap mode, we
- * render two reflected images to a double-length linear
- * texture and reflect that */
- CoglMatrix transform;
-
- cogl_matrix_init_identity (&transform);
- cogl_matrix_translate (&transform, tex_width, 0.0f, 0.0f);
- cogl_matrix_scale (&transform, -1.0f, 1.0f, 1.0f);
-
- cogl_framebuffer_transform (offscreen, &transform);
- cogl_primitive_draw (prim, offscreen, pipeline);
- }
-
- cogl_object_unref (prim);
- cogl_object_unref (pipeline);
-
- cogl_object_unref (offscreen);
- offscreen = NULL;
-
- gradient->textures = g_list_prepend (gradient->textures, entry);
- gradient->cache_entry.size = _cairo_cogl_linear_gradient_size (gradient);
-
-#ifdef DUMP_GRADIENTS_TO_PNG
- dump_gradient_to_png (tex);
-#endif
-
-#warning "FIXME:"
- /* XXX: it seems the documentation of _cairo_cache_insert isn't true - it
- * doesn't handle re-adding the same entry gracefully - the cache will
- * just keep on growing and then it will start randomly evicting things
- * pointlessly */
- /* we ignore errors here and just return an uncached gradient */
- if (likely (! _cairo_cache_insert (&device->linear_cache, &gradient->cache_entry)))
- _cairo_cogl_linear_gradient_reference (gradient);
-
- *gradient_out = gradient;
- return CAIRO_INT_STATUS_SUCCESS;
-
-BAIL:
- free (entry);
- if (gradient)
- _cairo_cogl_linear_gradient_destroy (gradient);
- if (offscreen)
- cogl_object_unref (offscreen);
- return status;
-}