Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* cairo - a vector graphics library with display and print output
  2.  *
  3.  * Copyright © 2009 T. Zachary Laine
  4.  * Copyright © 2010 Eric Anholt
  5.  * Copyright © 2010 Red Hat, Inc
  6.  * Copyright © 2010 Linaro Limited
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it either under the terms of the GNU Lesser General Public
  10.  * License version 2.1 as published by the Free Software Foundation
  11.  * (the "LGPL") or, at your option, under the terms of the Mozilla
  12.  * Public License Version 1.1 (the "MPL"). If you do not alter this
  13.  * notice, a recipient may use your version of this file under either
  14.  * the MPL or the LGPL.
  15.  *
  16.  * You should have received a copy of the LGPL along with this library
  17.  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
  19.  * You should have received a copy of the MPL along with this library
  20.  * in the file COPYING-MPL-1.1
  21.  *
  22.  * The contents of this file are subject to the Mozilla Public License
  23.  * Version 1.1 (the "License"); you may not use this file except in
  24.  * compliance with the License. You may obtain a copy of the License at
  25.  * http://www.mozilla.org/MPL/
  26.  *
  27.  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
  28.  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
  29.  * the specific language governing rights and limitations.
  30.  *
  31.  * The Original Code is the cairo graphics library.
  32.  *
  33.  * The Initial Developer of the Original Code is T. Zachary Laine.
  34.  *
  35.  * Contributor(s):
  36.  *      Benjamin Otte <otte@gnome.org>
  37.  *      Eric Anholt <eric@anholt.net>
  38.  *      T. Zachary Laine <whatwasthataddress@gmail.com>
  39.  *      Alexandros Frantzis <alexandros.frantzis@linaro.org>
  40.  */
  41.  
  42. #include "cairoint.h"
  43. #include "cairo-gl-private.h"
  44. #include "cairo-error-private.h"
  45. #include "cairo-output-stream-private.h"
  46.  
  47. static cairo_status_t
  48. _cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
  49.                                    cairo_gl_shader_t *shader,
  50.                                    cairo_gl_var_type_t src,
  51.                                    cairo_gl_var_type_t mask,
  52.                                    cairo_bool_t use_coverage,
  53.                                    const char *fragment_text);
  54.  
  55. typedef struct _cairo_shader_cache_entry {
  56.     cairo_cache_entry_t base;
  57.  
  58.     unsigned vertex;
  59.  
  60.     cairo_gl_operand_type_t src;
  61.     cairo_gl_operand_type_t mask;
  62.     cairo_gl_operand_type_t dest;
  63.     cairo_bool_t use_coverage;
  64.  
  65.     cairo_gl_shader_in_t in;
  66.     GLint src_gl_filter;
  67.     cairo_bool_t src_border_fade;
  68.     cairo_extend_t src_extend;
  69.     GLint mask_gl_filter;
  70.     cairo_bool_t mask_border_fade;
  71.     cairo_extend_t mask_extend;
  72.  
  73.     cairo_gl_context_t *ctx; /* XXX: needed to destroy the program */
  74.     cairo_gl_shader_t shader;
  75. } cairo_shader_cache_entry_t;
  76.  
  77. static cairo_bool_t
  78. _cairo_gl_shader_cache_equal_desktop (const void *key_a, const void *key_b)
  79. {
  80.     const cairo_shader_cache_entry_t *a = key_a;
  81.     const cairo_shader_cache_entry_t *b = key_b;
  82.     cairo_bool_t both_have_npot_repeat =
  83.         a->ctx->has_npot_repeat && b->ctx->has_npot_repeat;
  84.  
  85.     return (a->vertex == b->vertex &&
  86.             a->src  == b->src  &&
  87.             a->mask == b->mask &&
  88.             a->dest == b->dest &&
  89.             a->use_coverage == b->use_coverage &&
  90.             a->in   == b->in &&
  91.             (both_have_npot_repeat || a->src_extend == b->src_extend) &&
  92.             (both_have_npot_repeat || a->mask_extend == b->mask_extend));
  93. }
  94.  
  95. /*
  96.  * For GLES2 we use more complicated shaders to implement missing GL
  97.  * features. In this case we need more parameters to uniquely identify
  98.  * a shader (vs _cairo_gl_shader_cache_equal_desktop()).
  99.  */
  100. static cairo_bool_t
  101. _cairo_gl_shader_cache_equal_gles2 (const void *key_a, const void *key_b)
  102. {
  103.     const cairo_shader_cache_entry_t *a = key_a;
  104.     const cairo_shader_cache_entry_t *b = key_b;
  105.     cairo_bool_t both_have_npot_repeat =
  106.         a->ctx->has_npot_repeat && b->ctx->has_npot_repeat;
  107.  
  108.     return (a->vertex == b->vertex &&
  109.             a->src  == b->src  &&
  110.             a->mask == b->mask &&
  111.             a->dest == b->dest &&
  112.             a->use_coverage == b->use_coverage &&
  113.             a->in   == b->in   &&
  114.             a->src_gl_filter == b->src_gl_filter &&
  115.             a->src_border_fade == b->src_border_fade &&
  116.             (both_have_npot_repeat || a->src_extend == b->src_extend) &&
  117.             a->mask_gl_filter == b->mask_gl_filter &&
  118.             a->mask_border_fade == b->mask_border_fade &&
  119.             (both_have_npot_repeat || a->mask_extend == b->mask_extend));
  120. }
  121.  
  122. static unsigned long
  123. _cairo_gl_shader_cache_hash (const cairo_shader_cache_entry_t *entry)
  124. {
  125.     return ((entry->src << 24) | (entry->mask << 16) | (entry->dest << 8) | (entry->in << 1) | entry->use_coverage) ^ entry->vertex;
  126. }
  127.  
  128. static void
  129. _cairo_gl_shader_cache_destroy (void *data)
  130. {
  131.     cairo_shader_cache_entry_t *entry = data;
  132.  
  133.     _cairo_gl_shader_fini (entry->ctx, &entry->shader);
  134.     if (entry->ctx->current_shader == &entry->shader)
  135.         entry->ctx->current_shader = NULL;
  136.     free (entry);
  137. }
  138.  
  139. static void
  140. _cairo_gl_shader_init (cairo_gl_shader_t *shader)
  141. {
  142.     shader->fragment_shader = 0;
  143.     shader->program = 0;
  144. }
  145.  
  146. cairo_status_t
  147. _cairo_gl_context_init_shaders (cairo_gl_context_t *ctx)
  148. {
  149.     static const char *fill_fs_source =
  150.         "#ifdef GL_ES\n"
  151.         "precision mediump float;\n"
  152.         "#endif\n"
  153.         "uniform vec4 color;\n"
  154.         "void main()\n"
  155.         "{\n"
  156.         "       gl_FragColor = color;\n"
  157.         "}\n";
  158.     cairo_status_t status;
  159.  
  160.     if (_cairo_gl_get_version () >= CAIRO_GL_VERSION_ENCODE (2, 0) ||
  161.         (_cairo_gl_has_extension ("GL_ARB_shader_objects") &&
  162.          _cairo_gl_has_extension ("GL_ARB_fragment_shader") &&
  163.          _cairo_gl_has_extension ("GL_ARB_vertex_shader"))) {
  164.         ctx->has_shader_support = TRUE;
  165.     } else {
  166.         ctx->has_shader_support = FALSE;
  167.         fprintf (stderr, "Error: The cairo gl backend requires shader support!\n");
  168.         return CAIRO_STATUS_DEVICE_ERROR;
  169.     }
  170.  
  171.     memset (ctx->vertex_shaders, 0, sizeof (ctx->vertex_shaders));
  172.  
  173.     status = _cairo_cache_init (&ctx->shaders,
  174.                                 ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ?
  175.                                     _cairo_gl_shader_cache_equal_desktop :
  176.                                     _cairo_gl_shader_cache_equal_gles2,
  177.                                 NULL,
  178.                                 _cairo_gl_shader_cache_destroy,
  179.                                 CAIRO_GL_MAX_SHADERS_PER_CONTEXT);
  180.     if (unlikely (status))
  181.         return status;
  182.  
  183.     _cairo_gl_shader_init (&ctx->fill_rectangles_shader);
  184.     status = _cairo_gl_shader_compile_and_link (ctx,
  185.                                                 &ctx->fill_rectangles_shader,
  186.                                                 CAIRO_GL_VAR_NONE,
  187.                                                 CAIRO_GL_VAR_NONE,
  188.                                                 FALSE,
  189.                                                 fill_fs_source);
  190.     if (unlikely (status))
  191.         return status;
  192.  
  193.     return CAIRO_STATUS_SUCCESS;
  194. }
  195.  
  196. void
  197. _cairo_gl_context_fini_shaders (cairo_gl_context_t *ctx)
  198. {
  199.     int i;
  200.  
  201.     for (i = 0; i <= CAIRO_GL_VAR_TYPE_MAX; i++) {
  202.         if (ctx->vertex_shaders[i])
  203.             ctx->dispatch.DeleteShader (ctx->vertex_shaders[i]);
  204.     }
  205.  
  206.     _cairo_cache_fini (&ctx->shaders);
  207. }
  208.  
  209. void
  210. _cairo_gl_shader_fini (cairo_gl_context_t *ctx,
  211.                        cairo_gl_shader_t *shader)
  212. {
  213.     if (shader->fragment_shader)
  214.         ctx->dispatch.DeleteShader (shader->fragment_shader);
  215.  
  216.     if (shader->program)
  217.         ctx->dispatch.DeleteProgram (shader->program);
  218. }
  219.  
  220. static const char *operand_names[] = { "source", "mask", "dest" };
  221.  
  222. static cairo_gl_var_type_t
  223. cairo_gl_operand_get_var_type (cairo_gl_operand_t *operand)
  224. {
  225.     switch (operand->type) {
  226.     default:
  227.     case CAIRO_GL_OPERAND_COUNT:
  228.         ASSERT_NOT_REACHED;
  229.     case CAIRO_GL_OPERAND_NONE:
  230.     case CAIRO_GL_OPERAND_CONSTANT:
  231.         return CAIRO_GL_VAR_NONE;
  232.     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
  233.     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
  234.     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
  235.     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
  236.         return operand->gradient.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
  237.     case CAIRO_GL_OPERAND_TEXTURE:
  238.         return operand->texture.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
  239.     }
  240. }
  241.  
  242. static void
  243. cairo_gl_shader_emit_variable (cairo_output_stream_t *stream,
  244.                                cairo_gl_var_type_t type,
  245.                                cairo_gl_tex_t name)
  246. {
  247.     switch (type) {
  248.     default:
  249.         ASSERT_NOT_REACHED;
  250.     case CAIRO_GL_VAR_NONE:
  251.         break;
  252.     case CAIRO_GL_VAR_TEXCOORDS:
  253.         _cairo_output_stream_printf (stream,
  254.                                      "attribute vec4 MultiTexCoord%d;\n"
  255.                                      "varying vec2 %s_texcoords;\n",
  256.                                      name,
  257.                                      operand_names[name]);
  258.         break;
  259.     case CAIRO_GL_VAR_TEXGEN:
  260.         _cairo_output_stream_printf (stream,
  261.                                      "uniform mat3 %s_texgen;\n"
  262.                                      "varying vec2 %s_texcoords;\n",
  263.                                      operand_names[name],
  264.                                      operand_names[name]);
  265.         break;
  266.     }
  267. }
  268.  
  269. static void
  270. cairo_gl_shader_emit_vertex (cairo_output_stream_t *stream,
  271.                              cairo_gl_var_type_t type,
  272.                              cairo_gl_tex_t name)
  273. {
  274.     switch (type) {
  275.     default:
  276.         ASSERT_NOT_REACHED;
  277.     case CAIRO_GL_VAR_NONE:
  278.         break;
  279.     case CAIRO_GL_VAR_TEXCOORDS:
  280.         _cairo_output_stream_printf (stream,
  281.                                      "    %s_texcoords = MultiTexCoord%d.xy;\n",
  282.                                      operand_names[name], name);
  283.         break;
  284.  
  285.     case CAIRO_GL_VAR_TEXGEN:
  286.         _cairo_output_stream_printf (stream,
  287.                                      "    %s_texcoords = (%s_texgen * Vertex.xyw).xy;\n",
  288.                                      operand_names[name], operand_names[name]);
  289.         break;
  290.     }
  291. }
  292.  
  293. static void
  294. cairo_gl_shader_dcl_coverage (cairo_output_stream_t *stream)
  295. {
  296.     _cairo_output_stream_printf (stream, "varying float coverage;\n");
  297. }
  298.  
  299. static void
  300. cairo_gl_shader_def_coverage (cairo_output_stream_t *stream)
  301. {
  302.     _cairo_output_stream_printf (stream, "    coverage = Color.a;\n");
  303. }
  304.  
  305. static cairo_status_t
  306. cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
  307.                                    cairo_gl_var_type_t mask,
  308.                                    cairo_bool_t use_coverage,
  309.                                    cairo_gl_var_type_t dest,
  310.                                    char **out)
  311. {
  312.     cairo_output_stream_t *stream = _cairo_memory_stream_create ();
  313.     unsigned char *source;
  314.     unsigned long length;
  315.     cairo_status_t status;
  316.  
  317.     cairo_gl_shader_emit_variable (stream, src, CAIRO_GL_TEX_SOURCE);
  318.     cairo_gl_shader_emit_variable (stream, mask, CAIRO_GL_TEX_MASK);
  319.     if (use_coverage)
  320.         cairo_gl_shader_dcl_coverage (stream);
  321.  
  322.     _cairo_output_stream_printf (stream,
  323.                                  "attribute vec4 Vertex;\n"
  324.                                  "attribute vec4 Color;\n"
  325.                                  "uniform mat4 ModelViewProjectionMatrix;\n"
  326.                                  "void main()\n"
  327.                                  "{\n"
  328.                                  "    gl_Position = ModelViewProjectionMatrix * Vertex;\n");
  329.  
  330.     cairo_gl_shader_emit_vertex (stream, src, CAIRO_GL_TEX_SOURCE);
  331.     cairo_gl_shader_emit_vertex (stream, mask, CAIRO_GL_TEX_MASK);
  332.     if (use_coverage)
  333.         cairo_gl_shader_def_coverage (stream);
  334.  
  335.     _cairo_output_stream_write (stream,
  336.                                 "}\n\0", 3);
  337.  
  338.     status = _cairo_memory_stream_destroy (stream, &source, &length);
  339.     if (unlikely (status))
  340.         return status;
  341.  
  342.     *out = (char *) source;
  343.     return CAIRO_STATUS_SUCCESS;
  344. }
  345.  
  346. /*
  347.  * Returns whether an operand needs a special border fade fragment shader
  348.  * to simulate the GL_CLAMP_TO_BORDER wrapping method that is missing in GLES2.
  349.  */
  350. static cairo_bool_t
  351. _cairo_gl_shader_needs_border_fade (cairo_gl_operand_t *operand)
  352. {
  353.     cairo_extend_t extend =_cairo_gl_operand_get_extend (operand);
  354.  
  355.     return extend == CAIRO_EXTEND_NONE &&
  356.            (operand->type == CAIRO_GL_OPERAND_TEXTURE ||
  357.             operand->type == CAIRO_GL_OPERAND_LINEAR_GRADIENT ||
  358.             operand->type == CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE ||
  359.             operand->type == CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0);
  360. }
  361.  
  362. static void
  363. cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
  364.                             cairo_gl_context_t *ctx,
  365.                             cairo_gl_operand_t *op,
  366.                             cairo_gl_tex_t name)
  367. {
  368.     const char *namestr = operand_names[name];
  369.     const char *rectstr = (ctx->tex_target == GL_TEXTURE_RECTANGLE ? "Rect" : "");
  370.  
  371.     switch (op->type) {
  372.     case CAIRO_GL_OPERAND_COUNT:
  373.     default:
  374.         ASSERT_NOT_REACHED;
  375.         break;
  376.     case CAIRO_GL_OPERAND_NONE:
  377.         _cairo_output_stream_printf (stream,
  378.             "vec4 get_%s()\n"
  379.             "{\n"
  380.             "    return vec4 (0, 0, 0, 1);\n"
  381.             "}\n",
  382.             namestr);
  383.         break;
  384.     case CAIRO_GL_OPERAND_CONSTANT:
  385.         _cairo_output_stream_printf (stream,
  386.             "uniform vec4 %s_constant;\n"
  387.             "vec4 get_%s()\n"
  388.             "{\n"
  389.             "    return %s_constant;\n"
  390.             "}\n",
  391.             namestr, namestr, namestr);
  392.         break;
  393.     case CAIRO_GL_OPERAND_TEXTURE:
  394.         _cairo_output_stream_printf (stream,
  395.              "uniform sampler2D%s %s_sampler;\n"
  396.              "uniform vec2 %s_texdims;\n"
  397.              "varying vec2 %s_texcoords;\n"
  398.              "vec4 get_%s()\n"
  399.              "{\n",
  400.              rectstr, namestr, namestr, namestr, namestr);
  401.         if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
  402.             _cairo_gl_shader_needs_border_fade (op))
  403.         {
  404.             _cairo_output_stream_printf (stream,
  405.                 "    vec2 border_fade = %s_border_fade (%s_texcoords, %s_texdims);\n"
  406.                 "    vec4 texel = texture2D%s (%s_sampler, %s_texcoords);\n"
  407.                 "    return texel * border_fade.x * border_fade.y;\n"
  408.                 "}\n",
  409.                 namestr, namestr, namestr, rectstr, namestr, namestr);
  410.         }
  411.         else
  412.         {
  413.             _cairo_output_stream_printf (stream,
  414.                 "    return texture2D%s (%s_sampler, %s_wrap (%s_texcoords));\n"
  415.                 "}\n",
  416.                 rectstr, namestr, namestr, namestr);
  417.         }
  418.         break;
  419.     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
  420.         _cairo_output_stream_printf (stream,
  421.             "varying vec2 %s_texcoords;\n"
  422.             "uniform vec2 %s_texdims;\n"
  423.             "uniform sampler2D%s %s_sampler;\n"
  424.             "\n"
  425.             "vec4 get_%s()\n"
  426.             "{\n",
  427.             namestr, namestr, rectstr, namestr, namestr);
  428.         if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
  429.             _cairo_gl_shader_needs_border_fade (op))
  430.         {
  431.             _cairo_output_stream_printf (stream,
  432.                 "    float border_fade = %s_border_fade (%s_texcoords.x, %s_texdims.x);\n"
  433.                 "    vec4 texel = texture2D%s (%s_sampler, vec2 (%s_texcoords.x, 0.5));\n"
  434.                 "    return texel * border_fade;\n"
  435.                 "}\n",
  436.                 namestr, namestr, namestr, rectstr, namestr, namestr);
  437.         }
  438.         else
  439.         {
  440.             _cairo_output_stream_printf (stream,
  441.                 "    return texture2D%s (%s_sampler, %s_wrap (vec2 (%s_texcoords.x, 0.5)));\n"
  442.                 "}\n",
  443.                 rectstr, namestr, namestr, namestr);
  444.         }
  445.         break;
  446.     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
  447.         _cairo_output_stream_printf (stream,
  448.             "varying vec2 %s_texcoords;\n"
  449.             "uniform vec2 %s_texdims;\n"
  450.             "uniform sampler2D%s %s_sampler;\n"
  451.             "uniform vec3 %s_circle_d;\n"
  452.             "uniform float %s_radius_0;\n"
  453.             "\n"
  454.             "vec4 get_%s()\n"
  455.             "{\n"
  456.             "    vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
  457.             "    \n"
  458.             "    float B = dot (pos, %s_circle_d);\n"
  459.             "    float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
  460.             "    \n"
  461.             "    float t = 0.5 * C / B;\n"
  462.             "    float is_valid = step (-%s_radius_0, t * %s_circle_d.z);\n",
  463.             namestr, namestr, rectstr, namestr, namestr, namestr, namestr,
  464.             namestr, namestr, namestr, namestr, namestr);
  465.         if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
  466.             _cairo_gl_shader_needs_border_fade (op))
  467.         {
  468.             _cairo_output_stream_printf (stream,
  469.                 "    float border_fade = %s_border_fade (t, %s_texdims.x);\n"
  470.                 "    vec4 texel = texture2D%s (%s_sampler, vec2 (t, 0.5));\n"
  471.                 "    return mix (vec4 (0.0), texel * border_fade, is_valid);\n"
  472.                 "}\n",
  473.                 namestr, namestr, rectstr, namestr);
  474.         }
  475.         else
  476.         {
  477.             _cairo_output_stream_printf (stream,
  478.                 "    vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2 (t, 0.5)));\n"
  479.                 "    return mix (vec4 (0.0), texel, is_valid);\n"
  480.                 "}\n",
  481.                 rectstr, namestr, namestr);
  482.         }
  483.         break;
  484.     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
  485.         _cairo_output_stream_printf (stream,
  486.             "varying vec2 %s_texcoords;\n"
  487.             "uniform vec2 %s_texdims;\n"
  488.             "uniform sampler2D%s %s_sampler;\n"
  489.             "uniform vec3 %s_circle_d;\n"
  490.             "uniform float %s_a;\n"
  491.             "uniform float %s_radius_0;\n"
  492.             "\n"
  493.             "vec4 get_%s()\n"
  494.             "{\n"
  495.             "    vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
  496.             "    \n"
  497.             "    float B = dot (pos, %s_circle_d);\n"
  498.             "    float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
  499.             "    \n"
  500.             "    float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
  501.             "    float sqrtdet = sqrt (abs (det));\n"
  502.             "    vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
  503.             "    \n"
  504.             "    vec2 is_valid = step (vec2 (0.0), t) * step (t, vec2(1.0));\n"
  505.             "    float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
  506.             "    \n"
  507.             "    float upper_t = mix (t.y, t.x, is_valid.x);\n",
  508.             namestr, namestr, rectstr, namestr, namestr, namestr, namestr,
  509.             namestr, namestr, namestr, namestr, namestr, namestr);
  510.         if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
  511.             _cairo_gl_shader_needs_border_fade (op))
  512.         {
  513.             _cairo_output_stream_printf (stream,
  514.                 "    float border_fade = %s_border_fade (upper_t, %s_texdims.x);\n"
  515.                 "    vec4 texel = texture2D%s (%s_sampler, vec2 (upper_t, 0.5));\n"
  516.                 "    return mix (vec4 (0.0), texel * border_fade, has_color);\n"
  517.                 "}\n",
  518.                 namestr, namestr, rectstr, namestr);
  519.         }
  520.         else
  521.         {
  522.             _cairo_output_stream_printf (stream,
  523.                 "    vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n"
  524.                 "    return mix (vec4 (0.0), texel, has_color);\n"
  525.                 "}\n",
  526.                 rectstr, namestr, namestr);
  527.         }
  528.         break;
  529.     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
  530.         _cairo_output_stream_printf (stream,
  531.             "varying vec2 %s_texcoords;\n"
  532.             "uniform sampler2D%s %s_sampler;\n"
  533.             "uniform vec3 %s_circle_d;\n"
  534.             "uniform float %s_a;\n"
  535.             "uniform float %s_radius_0;\n"
  536.             "\n"
  537.             "vec4 get_%s()\n"
  538.             "{\n"
  539.             "    vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n"
  540.             "    \n"
  541.             "    float B = dot (pos, %s_circle_d);\n"
  542.             "    float C = dot (pos, vec3 (pos.xy, -pos.z));\n"
  543.             "    \n"
  544.             "    float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n"
  545.             "    float sqrtdet = sqrt (abs (det));\n"
  546.             "    vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n"
  547.             "    \n"
  548.             "    vec2 is_valid = step (vec2 (-%s_radius_0), t * %s_circle_d.z);\n"
  549.             "    float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n"
  550.             "    \n"
  551.             "    float upper_t = mix (t.y, t.x, is_valid.x);\n"
  552.             "    vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n"
  553.             "    return mix (vec4 (0.0), texel, has_color);\n"
  554.             "}\n",
  555.             namestr, rectstr, namestr, namestr, namestr, namestr,
  556.             namestr, namestr, namestr, namestr, namestr,
  557.             namestr, namestr, namestr, rectstr, namestr, namestr);
  558.         break;
  559.     }
  560. }
  561.  
  562. /*
  563.  * Emits the border fade functions used by an operand.
  564.  *
  565.  * If bilinear filtering is used, the emitted function performs a linear
  566.  * fade to transparency effect in the intervals [-1/2n, 1/2n] and
  567.  * [1 - 1/2n, 1 + 1/2n] (n: texture size).
  568.  *
  569.  * If nearest filtering is used, the emitted function just returns
  570.  * 0.0 for all values outside [0, 1).
  571.  */
  572. static void
  573. _cairo_gl_shader_emit_border_fade (cairo_output_stream_t *stream,
  574.                                    cairo_gl_operand_t *operand,
  575.                                    cairo_gl_tex_t name)
  576. {
  577.     const char *namestr = operand_names[name];
  578.     GLint gl_filter = _cairo_gl_operand_get_gl_filter (operand);
  579.  
  580.     /* 2D version */
  581.     _cairo_output_stream_printf (stream,
  582.         "vec2 %s_border_fade (vec2 coords, vec2 dims)\n"
  583.         "{\n",
  584.         namestr);
  585.  
  586.     if (gl_filter == GL_LINEAR)
  587.         _cairo_output_stream_printf (stream,
  588.             "    return clamp(-abs(dims * (coords - 0.5)) + (dims + vec2(1.0)) * 0.5, 0.0, 1.0);\n");
  589.     else
  590.         _cairo_output_stream_printf (stream,
  591.             "    bvec2 in_tex1 = greaterThanEqual (coords, vec2 (0.0));\n"
  592.             "    bvec2 in_tex2 = lessThan (coords, vec2 (1.0));\n"
  593.             "    return vec2 (float (all (in_tex1) && all (in_tex2)));\n");
  594.  
  595.     _cairo_output_stream_printf (stream, "}\n");
  596.  
  597.     /* 1D version */
  598.     _cairo_output_stream_printf (stream,
  599.         "float %s_border_fade (float x, float dim)\n"
  600.         "{\n",
  601.         namestr);
  602.     if (gl_filter == GL_LINEAR)
  603.         _cairo_output_stream_printf (stream,
  604.             "    return clamp(-abs(dim * (x - 0.5)) + (dim + 1.0) * 0.5, 0.0, 1.0);\n");
  605.     else
  606.         _cairo_output_stream_printf (stream,
  607.             "    bool in_tex = x >= 0.0 && x < 1.0;\n"
  608.             "    return float (in_tex);\n");
  609.  
  610.     _cairo_output_stream_printf (stream, "}\n");
  611. }
  612.  
  613. /*
  614.  * Emits the wrap function used by an operand.
  615.  *
  616.  * In OpenGL ES 2.0, repeat wrap modes (GL_REPEAT and GL_MIRRORED REPEAT) are
  617.  * only available for NPOT textures if the GL_OES_texture_npot is supported.
  618.  * If GL_OES_texture_npot is not supported, we need to implement the wrapping
  619.  * functionality in the shader.
  620.  */
  621. static void
  622. _cairo_gl_shader_emit_wrap (cairo_gl_context_t *ctx,
  623.                             cairo_output_stream_t *stream,
  624.                             cairo_gl_operand_t *operand,
  625.                             cairo_gl_tex_t name)
  626. {
  627.     const char *namestr = operand_names[name];
  628.     cairo_extend_t extend = _cairo_gl_operand_get_extend (operand);
  629.  
  630.     _cairo_output_stream_printf (stream,
  631.         "vec2 %s_wrap(vec2 coords)\n"
  632.         "{\n",
  633.         namestr);
  634.  
  635.     if (! ctx->has_npot_repeat &&
  636.         (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT))
  637.     {
  638.         if (extend == CAIRO_EXTEND_REPEAT) {
  639.             _cairo_output_stream_printf (stream,
  640.                 "    return fract(coords);\n");
  641.         } else { /* CAIRO_EXTEND_REFLECT */
  642.             _cairo_output_stream_printf (stream,
  643.                 "    return mix(fract(coords), 1.0 - fract(coords), floor(mod(coords, 2.0)));\n");
  644.         }
  645.     }
  646.     else
  647.     {
  648.         _cairo_output_stream_printf (stream, "    return coords;\n");
  649.     }
  650.  
  651.     _cairo_output_stream_printf (stream, "}\n");
  652. }
  653.  
  654. static cairo_status_t
  655. cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
  656.                                      cairo_gl_shader_in_t in,
  657.                                      cairo_gl_operand_t *src,
  658.                                      cairo_gl_operand_t *mask,
  659.                                      cairo_bool_t use_coverage,
  660.                                      cairo_gl_operand_type_t dest_type,
  661.                                      char **out)
  662. {
  663.     cairo_output_stream_t *stream = _cairo_memory_stream_create ();
  664.     unsigned char *source;
  665.     unsigned long length;
  666.     cairo_status_t status;
  667.     const char *coverage_str;
  668.  
  669.     _cairo_output_stream_printf (stream,
  670.         "#ifdef GL_ES\n"
  671.         "precision mediump float;\n"
  672.         "#endif\n");
  673.  
  674.     _cairo_gl_shader_emit_wrap (ctx, stream, src, CAIRO_GL_TEX_SOURCE);
  675.     _cairo_gl_shader_emit_wrap (ctx, stream, mask, CAIRO_GL_TEX_MASK);
  676.  
  677.     if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) {
  678.         if (_cairo_gl_shader_needs_border_fade (src))
  679.             _cairo_gl_shader_emit_border_fade (stream, src, CAIRO_GL_TEX_SOURCE);
  680.         if (_cairo_gl_shader_needs_border_fade (mask))
  681.             _cairo_gl_shader_emit_border_fade (stream, mask, CAIRO_GL_TEX_MASK);
  682.     }
  683.  
  684.     cairo_gl_shader_emit_color (stream, ctx, src, CAIRO_GL_TEX_SOURCE);
  685.     cairo_gl_shader_emit_color (stream, ctx, mask, CAIRO_GL_TEX_MASK);
  686.  
  687.     coverage_str = "";
  688.     if (use_coverage) {
  689.         _cairo_output_stream_printf (stream, "varying float coverage;\n");
  690.         coverage_str = " * coverage";
  691.     }
  692.  
  693.     _cairo_output_stream_printf (stream,
  694.         "void main()\n"
  695.         "{\n");
  696.     switch (in) {
  697.     case CAIRO_GL_SHADER_IN_COUNT:
  698.     default:
  699.         ASSERT_NOT_REACHED;
  700.     case CAIRO_GL_SHADER_IN_NORMAL:
  701.         _cairo_output_stream_printf (stream,
  702.             "    gl_FragColor = get_source() * get_mask().a%s;\n",
  703.             coverage_str);
  704.         break;
  705.     case CAIRO_GL_SHADER_IN_CA_SOURCE:
  706.         _cairo_output_stream_printf (stream,
  707.             "    gl_FragColor = get_source() * get_mask()%s;\n",
  708.             coverage_str);
  709.         break;
  710.     case CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA:
  711.         _cairo_output_stream_printf (stream,
  712.             "    gl_FragColor = get_source().a * get_mask()%s;\n",
  713.             coverage_str);
  714.         break;
  715.     }
  716.  
  717.     _cairo_output_stream_write (stream,
  718.                                 "}\n\0", 3);
  719.  
  720.     status = _cairo_memory_stream_destroy (stream, &source, &length);
  721.     if (unlikely (status))
  722.         return status;
  723.  
  724.     *out = (char *) source;
  725.     return CAIRO_STATUS_SUCCESS;
  726. }
  727.  
  728. static void
  729. compile_shader (cairo_gl_context_t *ctx,
  730.                 GLuint *shader,
  731.                 GLenum type,
  732.                 const char *source)
  733. {
  734.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  735.     GLint success, log_size, num_chars;
  736.     char *log;
  737.  
  738.     *shader = dispatch->CreateShader (type);
  739.     dispatch->ShaderSource (*shader, 1, &source, 0);
  740.     dispatch->CompileShader (*shader);
  741.     dispatch->GetShaderiv (*shader, GL_COMPILE_STATUS, &success);
  742.  
  743.     if (success)
  744.         return;
  745.  
  746.     dispatch->GetShaderiv (*shader, GL_INFO_LOG_LENGTH, &log_size);
  747.     if (log_size < 0) {
  748.         printf ("OpenGL shader compilation failed.\n");
  749.         ASSERT_NOT_REACHED;
  750.         return;
  751.     }
  752.  
  753.     log = _cairo_malloc (log_size + 1);
  754.     dispatch->GetShaderInfoLog (*shader, log_size, &num_chars, log);
  755.     log[num_chars] = '\0';
  756.  
  757.     printf ("OpenGL shader compilation failed.  Shader:\n%s\n", source);
  758.     printf ("OpenGL compilation log:\n%s\n", log);
  759.  
  760.     free (log);
  761.     ASSERT_NOT_REACHED;
  762. }
  763.  
  764. static void
  765. link_shader_program (cairo_gl_context_t *ctx,
  766.                      GLuint *program,
  767.                      GLuint vert,
  768.                      GLuint frag)
  769. {
  770.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  771.     GLint success, log_size, num_chars;
  772.     char *log;
  773.  
  774.     *program = dispatch->CreateProgram ();
  775.     dispatch->AttachShader (*program, vert);
  776.     dispatch->AttachShader (*program, frag);
  777.  
  778.     dispatch->BindAttribLocation (*program, CAIRO_GL_VERTEX_ATTRIB_INDEX,
  779.                                   "Vertex");
  780.     dispatch->BindAttribLocation (*program, CAIRO_GL_COLOR_ATTRIB_INDEX,
  781.                                   "Color");
  782.     dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD0_ATTRIB_INDEX,
  783.                                   "MultiTexCoord0");
  784.     dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD1_ATTRIB_INDEX,
  785.                                   "MultiTexCoord1");
  786.  
  787.     dispatch->LinkProgram (*program);
  788.     dispatch->GetProgramiv (*program, GL_LINK_STATUS, &success);
  789.     if (success)
  790.         return;
  791.  
  792.     dispatch->GetProgramiv (*program, GL_INFO_LOG_LENGTH, &log_size);
  793.     if (log_size < 0) {
  794.         printf ("OpenGL shader link failed.\n");
  795.         ASSERT_NOT_REACHED;
  796.         return;
  797.     }
  798.  
  799.     log = _cairo_malloc (log_size + 1);
  800.     dispatch->GetProgramInfoLog (*program, log_size, &num_chars, log);
  801.     log[num_chars] = '\0';
  802.  
  803.     printf ("OpenGL shader link failed:\n%s\n", log);
  804.     free (log);
  805.     ASSERT_NOT_REACHED;
  806. }
  807.  
  808. static GLint
  809. _cairo_gl_get_op_uniform_location(cairo_gl_context_t *ctx,
  810.                                   cairo_gl_shader_t  *shader,
  811.                                   cairo_gl_tex_t      tex_unit,
  812.                                   const char         *suffix)
  813. {
  814.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  815.     char uniform_name[100];
  816.     const char *unit_name[2] = { "source", "mask" };
  817.  
  818.     snprintf (uniform_name, sizeof (uniform_name), "%s_%s",
  819.               unit_name[tex_unit], suffix);
  820.  
  821.     return dispatch->GetUniformLocation (shader->program, uniform_name);
  822. }
  823.  
  824. static cairo_status_t
  825. _cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx,
  826.                                    cairo_gl_shader_t *shader,
  827.                                    cairo_gl_var_type_t src,
  828.                                    cairo_gl_var_type_t mask,
  829.                                    cairo_bool_t use_coverage,
  830.                                    const char *fragment_text)
  831. {
  832.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  833.     unsigned int vertex_shader;
  834.     cairo_status_t status;
  835.     int i;
  836.  
  837.     assert (shader->program == 0);
  838.  
  839.     vertex_shader = cairo_gl_var_type_hash (src, mask, use_coverage,
  840.                                             CAIRO_GL_VAR_NONE);
  841.     if (ctx->vertex_shaders[vertex_shader] == 0) {
  842.         char *source;
  843.  
  844.         status = cairo_gl_shader_get_vertex_source (src,
  845.                                                     mask,
  846.                                                     use_coverage,
  847.                                                     CAIRO_GL_VAR_NONE,
  848.                                                     &source);
  849.         if (unlikely (status))
  850.             goto FAILURE;
  851.  
  852.         compile_shader (ctx, &ctx->vertex_shaders[vertex_shader],
  853.                         GL_VERTEX_SHADER, source);
  854.         free (source);
  855.     }
  856.  
  857.     compile_shader (ctx, &shader->fragment_shader,
  858.                     GL_FRAGMENT_SHADER, fragment_text);
  859.  
  860.     link_shader_program (ctx, &shader->program,
  861.                          ctx->vertex_shaders[vertex_shader],
  862.                          shader->fragment_shader);
  863.  
  864.     shader->mvp_location =
  865.         dispatch->GetUniformLocation (shader->program,
  866.                                       "ModelViewProjectionMatrix");
  867.  
  868.     for (i = 0; i < 2; i++) {
  869.         shader->constant_location[i] =
  870.             _cairo_gl_get_op_uniform_location (ctx, shader, i, "constant");
  871.         shader->a_location[i] =
  872.             _cairo_gl_get_op_uniform_location (ctx, shader, i, "a");
  873.         shader->circle_d_location[i] =
  874.             _cairo_gl_get_op_uniform_location (ctx, shader, i, "circle_d");
  875.         shader->radius_0_location[i] =
  876.             _cairo_gl_get_op_uniform_location (ctx, shader, i, "radius_0");
  877.         shader->texdims_location[i] =
  878.             _cairo_gl_get_op_uniform_location (ctx, shader, i, "texdims");
  879.         shader->texgen_location[i] =
  880.             _cairo_gl_get_op_uniform_location (ctx, shader, i, "texgen");
  881.     }
  882.  
  883.     return CAIRO_STATUS_SUCCESS;
  884.  
  885.  FAILURE:
  886.     _cairo_gl_shader_fini (ctx, shader);
  887.     shader->fragment_shader = 0;
  888.     shader->program = 0;
  889.  
  890.     return status;
  891. }
  892.  
  893. /* We always bind the source to texture unit 0 if present, and mask to
  894.  * texture unit 1 if present, so we can just initialize these once at
  895.  * compile time.
  896.  */
  897. static void
  898. _cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx,
  899.                                cairo_gl_shader_t *shader)
  900. {
  901.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  902.     GLint location;
  903.     GLint saved_program;
  904.  
  905.     /* We have to save/restore the current program because we might be
  906.      * asked for a different program while a shader is bound.  This shouldn't
  907.      * be a performance issue, since this is only called once per compile.
  908.      */
  909.     glGetIntegerv (GL_CURRENT_PROGRAM, &saved_program);
  910.     dispatch->UseProgram (shader->program);
  911.  
  912.     location = dispatch->GetUniformLocation (shader->program, "source_sampler");
  913.     if (location != -1) {
  914.         dispatch->Uniform1i (location, CAIRO_GL_TEX_SOURCE);
  915.     }
  916.  
  917.     location = dispatch->GetUniformLocation (shader->program, "mask_sampler");
  918.     if (location != -1) {
  919.         dispatch->Uniform1i (location, CAIRO_GL_TEX_MASK);
  920.     }
  921.  
  922.     dispatch->UseProgram (saved_program);
  923. }
  924.  
  925. void
  926. _cairo_gl_shader_bind_float (cairo_gl_context_t *ctx,
  927.                              GLint location,
  928.                              float value)
  929. {
  930.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  931.     assert (location != -1);
  932.     dispatch->Uniform1f (location, value);
  933. }
  934.  
  935. void
  936. _cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx,
  937.                             GLint location,
  938.                             float value0,
  939.                             float value1)
  940. {
  941.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  942.     assert (location != -1);
  943.     dispatch->Uniform2f (location, value0, value1);
  944. }
  945.  
  946. void
  947. _cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx,
  948.                             GLint location,
  949.                             float value0,
  950.                             float value1,
  951.                             float value2)
  952. {
  953.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  954.     assert (location != -1);
  955.     dispatch->Uniform3f (location, value0, value1, value2);
  956. }
  957.  
  958. void
  959. _cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
  960.                             GLint location,
  961.                             float value0, float value1,
  962.                             float value2, float value3)
  963. {
  964.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  965.     assert (location != -1);
  966.     dispatch->Uniform4f (location, value0, value1, value2, value3);
  967. }
  968.  
  969. void
  970. _cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
  971.                               GLint location,
  972.                               const cairo_matrix_t* m)
  973. {
  974.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  975.     float gl_m[9] = {
  976.         m->xx, m->xy, m->x0,
  977.         m->yx, m->yy, m->y0,
  978.         0,     0,     1
  979.     };
  980.     assert (location != -1);
  981.     dispatch->UniformMatrix3fv (location, 1, GL_TRUE, gl_m);
  982. }
  983.  
  984. void
  985. _cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
  986.                                 GLint location, GLfloat* gl_m)
  987. {
  988.     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
  989.     assert (location != -1);
  990.     dispatch->UniformMatrix4fv (location, 1, GL_FALSE, gl_m);
  991. }
  992.  
  993. void
  994. _cairo_gl_set_shader (cairo_gl_context_t *ctx,
  995.                       cairo_gl_shader_t *shader)
  996. {
  997.     if (ctx->current_shader == shader)
  998.         return;
  999.  
  1000.     if (shader)
  1001.         ctx->dispatch.UseProgram (shader->program);
  1002.     else
  1003.         ctx->dispatch.UseProgram (0);
  1004.  
  1005.     ctx->current_shader = shader;
  1006. }
  1007.  
  1008. cairo_status_t
  1009. _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
  1010.                               cairo_gl_operand_t *source,
  1011.                               cairo_gl_operand_t *mask,
  1012.                               cairo_bool_t use_coverage,
  1013.                               cairo_gl_shader_in_t in,
  1014.                               cairo_gl_shader_t **shader)
  1015. {
  1016.     cairo_shader_cache_entry_t lookup, *entry;
  1017.     char *fs_source;
  1018.     cairo_status_t status;
  1019.  
  1020.     lookup.ctx = ctx;
  1021.  
  1022.     lookup.vertex = cairo_gl_var_type_hash (cairo_gl_operand_get_var_type (source),
  1023.                                             cairo_gl_operand_get_var_type (mask),
  1024.                                             use_coverage,
  1025.                                             CAIRO_GL_VAR_NONE);
  1026.  
  1027.     lookup.src = source->type;
  1028.     lookup.mask = mask->type;
  1029.     lookup.dest = CAIRO_GL_OPERAND_NONE;
  1030.     lookup.use_coverage = use_coverage;
  1031.     lookup.in = in;
  1032.     lookup.src_gl_filter = _cairo_gl_operand_get_gl_filter (source);
  1033.     lookup.src_border_fade = _cairo_gl_shader_needs_border_fade (source);
  1034.     lookup.src_extend = _cairo_gl_operand_get_extend (source);
  1035.     lookup.mask_gl_filter = _cairo_gl_operand_get_gl_filter (mask);
  1036.     lookup.mask_border_fade = _cairo_gl_shader_needs_border_fade (mask);
  1037.     lookup.mask_extend = _cairo_gl_operand_get_extend (mask);
  1038.     lookup.base.hash = _cairo_gl_shader_cache_hash (&lookup);
  1039.     lookup.base.size = 1;
  1040.  
  1041.     entry = _cairo_cache_lookup (&ctx->shaders, &lookup.base);
  1042.     if (entry) {
  1043.         assert (entry->shader.program);
  1044.         *shader = &entry->shader;
  1045.         return CAIRO_STATUS_SUCCESS;
  1046.     }
  1047.  
  1048.     status = cairo_gl_shader_get_fragment_source (ctx,
  1049.                                                   in,
  1050.                                                   source,
  1051.                                                   mask,
  1052.                                                   use_coverage,
  1053.                                                   CAIRO_GL_OPERAND_NONE,
  1054.                                                   &fs_source);
  1055.     if (unlikely (status))
  1056.         return status;
  1057.  
  1058.     entry = malloc (sizeof (cairo_shader_cache_entry_t));
  1059.     if (unlikely (entry == NULL)) {
  1060.         free (fs_source);
  1061.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1062.     }
  1063.  
  1064.     memcpy (entry, &lookup, sizeof (cairo_shader_cache_entry_t));
  1065.  
  1066.     entry->ctx = ctx;
  1067.     _cairo_gl_shader_init (&entry->shader);
  1068.     status = _cairo_gl_shader_compile_and_link (ctx,
  1069.                                                 &entry->shader,
  1070.                                                 cairo_gl_operand_get_var_type (source),
  1071.                                                 cairo_gl_operand_get_var_type (mask),
  1072.                                                 use_coverage,
  1073.                                                 fs_source);
  1074.     free (fs_source);
  1075.  
  1076.     if (unlikely (status)) {
  1077.         free (entry);
  1078.         return status;
  1079.     }
  1080.  
  1081.     _cairo_gl_shader_set_samplers (ctx, &entry->shader);
  1082.  
  1083.     status = _cairo_cache_insert (&ctx->shaders, &entry->base);
  1084.     if (unlikely (status)) {
  1085.         _cairo_gl_shader_fini (ctx, &entry->shader);
  1086.         free (entry);
  1087.         return status;
  1088.     }
  1089.  
  1090.     *shader = &entry->shader;
  1091.  
  1092.     return CAIRO_STATUS_SUCCESS;
  1093. }
  1094.