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 Eric Anholt
  4.  * Copyright © 2009 Chris Wilson
  5.  * Copyright © 2005,2010 Red Hat, Inc
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it either under the terms of the GNU Lesser General Public
  9.  * License version 2.1 as published by the Free Software Foundation
  10.  * (the "LGPL") or, at your option, under the terms of the Mozilla
  11.  * Public License Version 1.1 (the "MPL"). If you do not alter this
  12.  * notice, a recipient may use your version of this file under either
  13.  * the MPL or the LGPL.
  14.  *
  15.  * You should have received a copy of the LGPL along with this library
  16.  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
  17.  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
  18.  * You should have received a copy of the MPL along with this library
  19.  * in the file COPYING-MPL-1.1
  20.  *
  21.  * The contents of this file are subject to the Mozilla Public License
  22.  * Version 1.1 (the "License"); you may not use this file except in
  23.  * compliance with the License. You may obtain a copy of the License at
  24.  * http://www.mozilla.org/MPL/
  25.  *
  26.  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
  27.  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
  28.  * the specific language governing rights and limitations.
  29.  *
  30.  * The Original Code is the cairo graphics library.
  31.  *
  32.  * The Initial Developer of the Original Code is Red Hat, Inc.
  33.  *
  34.  * Contributor(s):
  35.  *      Benjamin Otte <otte@gnome.org>
  36.  *      Carl Worth <cworth@cworth.org>
  37.  *      Chris Wilson <chris@chris-wilson.co.uk>
  38.  *      Eric Anholt <eric@anholt.net>
  39.  */
  40.  
  41. #include "cairoint.h"
  42.  
  43. #include "cairo-gl-private.h"
  44.  
  45. #include "cairo-composite-rectangles-private.h"
  46. #include "cairo-compositor-private.h"
  47. #include "cairo-default-context-private.h"
  48. #include "cairo-error-private.h"
  49. #include "cairo-image-surface-inline.h"
  50. #include "cairo-surface-backend-private.h"
  51.  
  52. static const cairo_surface_backend_t _cairo_gl_surface_backend;
  53.  
  54. static cairo_status_t
  55. _cairo_gl_surface_flush (void *abstract_surface, unsigned flags);
  56.  
  57. static cairo_bool_t _cairo_surface_is_gl (cairo_surface_t *surface)
  58. {
  59.     return surface->backend == &_cairo_gl_surface_backend;
  60. }
  61.  
  62. static cairo_bool_t
  63. _cairo_gl_get_image_format_and_type_gles2 (pixman_format_code_t pixman_format,
  64.                                            GLenum *internal_format, GLenum *format,
  65.                                            GLenum *type, cairo_bool_t *has_alpha,
  66.                                            cairo_bool_t *needs_swap)
  67. {
  68.     cairo_bool_t is_little_endian = _cairo_is_little_endian ();
  69.  
  70.     *has_alpha = TRUE;
  71.  
  72.     switch ((int) pixman_format) {
  73.     case PIXMAN_a8r8g8b8:
  74.         *internal_format = GL_BGRA;
  75.         *format = GL_BGRA;
  76.         *type = GL_UNSIGNED_BYTE;
  77.         *needs_swap = !is_little_endian;
  78.         return TRUE;
  79.  
  80.     case PIXMAN_x8r8g8b8:
  81.         *internal_format = GL_BGRA;
  82.         *format = GL_BGRA;
  83.         *type = GL_UNSIGNED_BYTE;
  84.         *has_alpha = FALSE;
  85.         *needs_swap = !is_little_endian;
  86.         return TRUE;
  87.  
  88.     case PIXMAN_a8b8g8r8:
  89.         *internal_format = GL_RGBA;
  90.         *format = GL_RGBA;
  91.         *type = GL_UNSIGNED_BYTE;
  92.         *needs_swap = !is_little_endian;
  93.         return TRUE;
  94.  
  95.     case PIXMAN_x8b8g8r8:
  96.         *internal_format = GL_RGBA;
  97.         *format = GL_RGBA;
  98.         *type = GL_UNSIGNED_BYTE;
  99.         *has_alpha = FALSE;
  100.         *needs_swap = !is_little_endian;
  101.         return TRUE;
  102.  
  103.     case PIXMAN_b8g8r8a8:
  104.         *internal_format = GL_BGRA;
  105.         *format = GL_BGRA;
  106.         *type = GL_UNSIGNED_BYTE;
  107.         *needs_swap = is_little_endian;
  108.         return TRUE;
  109.  
  110.     case PIXMAN_b8g8r8x8:
  111.         *internal_format = GL_BGRA;
  112.         *format = GL_BGRA;
  113.         *type = GL_UNSIGNED_BYTE;
  114.         *has_alpha = FALSE;
  115.         *needs_swap = is_little_endian;
  116.         return TRUE;
  117.  
  118.     case PIXMAN_r8g8b8:
  119.         *internal_format = GL_RGB;
  120.         *format = GL_RGB;
  121.         *type = GL_UNSIGNED_BYTE;
  122.         *needs_swap = is_little_endian;
  123.         return TRUE;
  124.  
  125.     case PIXMAN_b8g8r8:
  126.         *internal_format = GL_RGB;
  127.         *format = GL_RGB;
  128.         *type = GL_UNSIGNED_BYTE;
  129.         *needs_swap = !is_little_endian;
  130.         return TRUE;
  131.  
  132.     case PIXMAN_r5g6b5:
  133.         *internal_format = GL_RGB;
  134.         *format = GL_RGB;
  135.         *type = GL_UNSIGNED_SHORT_5_6_5;
  136.         *needs_swap = FALSE;
  137.         return TRUE;
  138.  
  139.     case PIXMAN_b5g6r5:
  140.         *internal_format = GL_RGB;
  141.         *format = GL_RGB;
  142.         *type = GL_UNSIGNED_SHORT_5_6_5;
  143.         *needs_swap = TRUE;
  144.         return TRUE;
  145.  
  146.     case PIXMAN_a1b5g5r5:
  147.         *internal_format = GL_RGBA;
  148.         *format = GL_RGBA;
  149.         *type = GL_UNSIGNED_SHORT_5_5_5_1;
  150.         *needs_swap = TRUE;
  151.         return TRUE;
  152.  
  153.     case PIXMAN_x1b5g5r5:
  154.         *internal_format = GL_RGBA;
  155.         *format = GL_RGBA;
  156.         *type = GL_UNSIGNED_SHORT_5_5_5_1;
  157.         *has_alpha = FALSE;
  158.         *needs_swap = TRUE;
  159.         return TRUE;
  160.  
  161.     case PIXMAN_a8:
  162.         *internal_format = GL_ALPHA;
  163.         *format = GL_ALPHA;
  164.         *type = GL_UNSIGNED_BYTE;
  165.         *needs_swap = FALSE;
  166.         return TRUE;
  167.  
  168.     default:
  169.         return FALSE;
  170.     }
  171. }
  172.  
  173. static cairo_bool_t
  174. _cairo_gl_get_image_format_and_type_gl (pixman_format_code_t pixman_format,
  175.                                         GLenum *internal_format, GLenum *format,
  176.                                         GLenum *type, cairo_bool_t *has_alpha,
  177.                                         cairo_bool_t *needs_swap)
  178. {
  179.     *has_alpha = TRUE;
  180.     *needs_swap = FALSE;
  181.  
  182.     switch (pixman_format) {
  183.     case PIXMAN_a8r8g8b8:
  184.         *internal_format = GL_RGBA;
  185.         *format = GL_BGRA;
  186.         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
  187.         return TRUE;
  188.     case PIXMAN_x8r8g8b8:
  189.         *internal_format = GL_RGB;
  190.         *format = GL_BGRA;
  191.         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
  192.         *has_alpha = FALSE;
  193.         return TRUE;
  194.     case PIXMAN_a8b8g8r8:
  195.         *internal_format = GL_RGBA;
  196.         *format = GL_RGBA;
  197.         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
  198.         return TRUE;
  199.     case PIXMAN_x8b8g8r8:
  200.         *internal_format = GL_RGB;
  201.         *format = GL_RGBA;
  202.         *type = GL_UNSIGNED_INT_8_8_8_8_REV;
  203.         *has_alpha = FALSE;
  204.         return TRUE;
  205.     case PIXMAN_b8g8r8a8:
  206.         *internal_format = GL_RGBA;
  207.         *format = GL_BGRA;
  208.         *type = GL_UNSIGNED_INT_8_8_8_8;
  209.         return TRUE;
  210.     case PIXMAN_b8g8r8x8:
  211.         *internal_format = GL_RGB;
  212.         *format = GL_BGRA;
  213.         *type = GL_UNSIGNED_INT_8_8_8_8;
  214.         *has_alpha = FALSE;
  215.         return TRUE;
  216.     case PIXMAN_r8g8b8:
  217.         *internal_format = GL_RGB;
  218.         *format = GL_RGB;
  219.         *type = GL_UNSIGNED_BYTE;
  220.         return TRUE;
  221.     case PIXMAN_b8g8r8:
  222.         *internal_format = GL_RGB;
  223.         *format = GL_BGR;
  224.         *type = GL_UNSIGNED_BYTE;
  225.         return TRUE;
  226.     case PIXMAN_r5g6b5:
  227.         *internal_format = GL_RGB;
  228.         *format = GL_RGB;
  229.         *type = GL_UNSIGNED_SHORT_5_6_5;
  230.         return TRUE;
  231.     case PIXMAN_b5g6r5:
  232.         *internal_format = GL_RGB;
  233.         *format = GL_RGB;
  234.         *type = GL_UNSIGNED_SHORT_5_6_5_REV;
  235.         return TRUE;
  236.     case PIXMAN_a1r5g5b5:
  237.         *internal_format = GL_RGBA;
  238.         *format = GL_BGRA;
  239.         *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
  240.         return TRUE;
  241.     case PIXMAN_x1r5g5b5:
  242.         *internal_format = GL_RGB;
  243.         *format = GL_BGRA;
  244.         *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
  245.         *has_alpha = FALSE;
  246.         return TRUE;
  247.     case PIXMAN_a1b5g5r5:
  248.         *internal_format = GL_RGBA;
  249.         *format = GL_RGBA;
  250.         *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
  251.         return TRUE;
  252.     case PIXMAN_x1b5g5r5:
  253.         *internal_format = GL_RGB;
  254.         *format = GL_RGBA;
  255.         *type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
  256.         *has_alpha = FALSE;
  257.         return TRUE;
  258.     case PIXMAN_a8:
  259.         *internal_format = GL_ALPHA;
  260.         *format = GL_ALPHA;
  261.         *type = GL_UNSIGNED_BYTE;
  262.         return TRUE;
  263.  
  264.     case PIXMAN_a2b10g10r10:
  265.     case PIXMAN_x2b10g10r10:
  266.     case PIXMAN_a4r4g4b4:
  267.     case PIXMAN_x4r4g4b4:
  268.     case PIXMAN_a4b4g4r4:
  269.     case PIXMAN_x4b4g4r4:
  270.     case PIXMAN_r3g3b2:
  271.     case PIXMAN_b2g3r3:
  272.     case PIXMAN_a2r2g2b2:
  273.     case PIXMAN_a2b2g2r2:
  274.     case PIXMAN_c8:
  275.     case PIXMAN_x4a4:
  276.     /* case PIXMAN_x4c4: */
  277.     case PIXMAN_x4g4:
  278.     case PIXMAN_a4:
  279.     case PIXMAN_r1g2b1:
  280.     case PIXMAN_b1g2r1:
  281.     case PIXMAN_a1r1g1b1:
  282.     case PIXMAN_a1b1g1r1:
  283.     case PIXMAN_c4:
  284.     case PIXMAN_g4:
  285.     case PIXMAN_a1:
  286.     case PIXMAN_g1:
  287.     case PIXMAN_yuy2:
  288.     case PIXMAN_yv12:
  289.     case PIXMAN_x2r10g10b10:
  290.     case PIXMAN_a2r10g10b10:
  291.     case PIXMAN_r8g8b8x8:
  292.     case PIXMAN_r8g8b8a8:
  293.     case PIXMAN_x14r6g6b6:
  294.     default:
  295.         return FALSE;
  296.     }
  297. }
  298.  
  299. /*
  300.  * Extracts pixel data from an image surface.
  301.  */
  302. static cairo_status_t
  303. _cairo_gl_surface_extract_image_data (cairo_image_surface_t *image,
  304.                                       int x, int y,
  305.                                       int width, int height,
  306.                                       void **output)
  307. {
  308.     int cpp = PIXMAN_FORMAT_BPP (image->pixman_format) / 8;
  309.     char *data = _cairo_malloc_ab (width * height, cpp);
  310.     char *dst = data;
  311.     unsigned char *src = image->data + y * image->stride + x * cpp;
  312.     int i;
  313.  
  314.     if (unlikely (data == NULL))
  315.         return CAIRO_STATUS_NO_MEMORY;
  316.  
  317.     for (i = 0; i < height; i++) {
  318.         memcpy (dst, src, width * cpp);
  319.         src += image->stride;
  320.         dst += width * cpp;
  321.     }
  322.  
  323.     *output = data;
  324.  
  325.     return CAIRO_STATUS_SUCCESS;
  326. }
  327.  
  328. cairo_bool_t
  329. _cairo_gl_get_image_format_and_type (cairo_gl_flavor_t flavor,
  330.                                      pixman_format_code_t pixman_format,
  331.                                      GLenum *internal_format, GLenum *format,
  332.                                      GLenum *type, cairo_bool_t *has_alpha,
  333.                                      cairo_bool_t *needs_swap)
  334. {
  335.     if (flavor == CAIRO_GL_FLAVOR_DESKTOP)
  336.         return _cairo_gl_get_image_format_and_type_gl (pixman_format,
  337.                                                        internal_format, format,
  338.                                                        type, has_alpha,
  339.                                                        needs_swap);
  340.     else
  341.         return _cairo_gl_get_image_format_and_type_gles2 (pixman_format,
  342.                                                           internal_format, format,
  343.                                                           type, has_alpha,
  344.                                                           needs_swap);
  345.  
  346. }
  347.  
  348. cairo_bool_t
  349. _cairo_gl_operator_is_supported (cairo_operator_t op)
  350. {
  351.     return op < CAIRO_OPERATOR_SATURATE;
  352. }
  353.  
  354. static void
  355. _cairo_gl_surface_embedded_operand_init (cairo_gl_surface_t *surface)
  356. {
  357.     cairo_gl_operand_t *operand = &surface->operand;
  358.     cairo_surface_attributes_t *attributes = &operand->texture.attributes;
  359.  
  360.     memset (operand, 0, sizeof (cairo_gl_operand_t));
  361.  
  362.     operand->type = CAIRO_GL_OPERAND_TEXTURE;
  363.     operand->texture.surface = surface;
  364.     operand->texture.tex = surface->tex;
  365.  
  366.     if (_cairo_gl_device_requires_power_of_two_textures (surface->base.device)) {
  367.         cairo_matrix_init_identity (&attributes->matrix);
  368.     } else {
  369.         cairo_matrix_init_scale (&attributes->matrix,
  370.                                  1.0 / surface->width,
  371.                                  1.0 / surface->height);
  372.     }
  373.  
  374.     attributes->extend = CAIRO_EXTEND_NONE;
  375.     attributes->filter = CAIRO_FILTER_NEAREST;
  376. }
  377.  
  378. void
  379. _cairo_gl_surface_init (cairo_device_t *device,
  380.                         cairo_gl_surface_t *surface,
  381.                         cairo_content_t content,
  382.                         int width, int height)
  383. {
  384.     assert (width > 0 && height > 0);
  385.  
  386.     _cairo_surface_init (&surface->base,
  387.                          &_cairo_gl_surface_backend,
  388.                          device,
  389.                          content);
  390.  
  391.     surface->width = width;
  392.     surface->height = height;
  393.     surface->needs_update = FALSE;
  394.  
  395.     _cairo_gl_surface_embedded_operand_init (surface);
  396. }
  397.  
  398. static cairo_bool_t
  399. _cairo_gl_surface_size_valid_for_context (cairo_gl_context_t *ctx,
  400.                                           int width, int height)
  401. {
  402.     return width > 0 && height > 0 &&
  403.         width <= ctx->max_framebuffer_size &&
  404.         height <= ctx->max_framebuffer_size;
  405. }
  406.  
  407. static cairo_bool_t
  408. _cairo_gl_surface_size_valid (cairo_gl_surface_t *surface,
  409.                               int width, int height)
  410. {
  411.     cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
  412.     return _cairo_gl_surface_size_valid_for_context (ctx, width, height);
  413. }
  414.  
  415. static cairo_surface_t *
  416. _cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t   *ctx,
  417.                                               cairo_content_t       content,
  418.                                               GLuint                tex,
  419.                                               int                   width,
  420.                                               int                   height)
  421. {
  422.     cairo_gl_surface_t *surface;
  423.  
  424.     surface = calloc (1, sizeof (cairo_gl_surface_t));
  425.     if (unlikely (surface == NULL))
  426.         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
  427.  
  428.     surface->tex = tex;
  429.     _cairo_gl_surface_init (&ctx->base, surface, content, width, height);
  430.  
  431.     surface->supports_msaa = ctx->supports_msaa;
  432.     surface->supports_stencil = TRUE;
  433.  
  434.     /* Create the texture used to store the surface's data. */
  435.     _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
  436.     glBindTexture (ctx->tex_target, surface->tex);
  437.     glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  438.     glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  439.  
  440.     return &surface->base;
  441. }
  442.  
  443. static cairo_surface_t *
  444. _create_scratch_internal (cairo_gl_context_t *ctx,
  445.                           cairo_content_t content,
  446.                           int width,
  447.                           int height,
  448.                           cairo_bool_t for_caching)
  449. {
  450.     cairo_gl_surface_t *surface;
  451.     GLenum format;
  452.     GLuint tex;
  453.  
  454.     glGenTextures (1, &tex);
  455.     surface = (cairo_gl_surface_t *)
  456.         _cairo_gl_surface_create_scratch_for_texture (ctx, content,
  457.                                                       tex, width, height);
  458.     if (unlikely (surface->base.status))
  459.         return &surface->base;
  460.  
  461.     surface->owns_tex = TRUE;
  462.  
  463.     /* adjust the texture size after setting our real extents */
  464.     if (width < 1)
  465.         width = 1;
  466.     if (height < 1)
  467.         height = 1;
  468.  
  469.     switch (content) {
  470.     default:
  471.         ASSERT_NOT_REACHED;
  472.     case CAIRO_CONTENT_COLOR_ALPHA:
  473.         format = GL_RGBA;
  474.         break;
  475.     case CAIRO_CONTENT_ALPHA:
  476.         /* When using GL_ALPHA, compositing doesn't work properly, but for
  477.          * caching surfaces, we are just uploading pixel data, so it isn't
  478.          * an issue. */
  479.         if (for_caching)
  480.             format = GL_ALPHA;
  481.         else
  482.             format = GL_RGBA;
  483.         break;
  484.     case CAIRO_CONTENT_COLOR:
  485.         /* GL_RGB is almost what we want here -- sampling 1 alpha when
  486.          * texturing, using 1 as destination alpha factor in blending,
  487.          * etc.  However, when filtering with GL_CLAMP_TO_BORDER, the
  488.          * alpha channel of the border color will also be clamped to
  489.          * 1, when we actually want the border color we explicitly
  490.          * specified.  So, we have to store RGBA, and fill the alpha
  491.          * channel with 1 when blending.
  492.          */
  493.         format = GL_RGBA;
  494.         break;
  495.     }
  496.  
  497.     glTexImage2D (ctx->tex_target, 0, format, width, height, 0,
  498.                   format, GL_UNSIGNED_BYTE, NULL);
  499.  
  500.     return &surface->base;
  501. }
  502.  
  503. cairo_surface_t *
  504. _cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
  505.                                   cairo_content_t       content,
  506.                                   int                   width,
  507.                                   int                   height)
  508. {
  509.     return _create_scratch_internal (ctx, content, width, height, FALSE);
  510. }
  511.  
  512. cairo_surface_t *
  513. _cairo_gl_surface_create_scratch_for_caching (cairo_gl_context_t *ctx,
  514.                                               cairo_content_t content,
  515.                                               int width,
  516.                                               int height)
  517. {
  518.     return _create_scratch_internal (ctx, content, width, height, TRUE);
  519. }
  520.  
  521. static cairo_status_t
  522. _cairo_gl_surface_clear (cairo_gl_surface_t  *surface,
  523.                          const cairo_color_t *color)
  524. {
  525.     cairo_gl_context_t *ctx;
  526.     cairo_status_t status;
  527.     double r, g, b, a;
  528.  
  529.     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
  530.     if (unlikely (status))
  531.         return status;
  532.  
  533.     _cairo_gl_context_set_destination (ctx, surface, surface->msaa_active);
  534.     if (surface->base.content & CAIRO_CONTENT_COLOR) {
  535.         r = color->red   * color->alpha;
  536.         g = color->green * color->alpha;
  537.         b = color->blue  * color->alpha;
  538.     } else {
  539.         r = g = b = 0;
  540.     }
  541.     if (surface->base.content & CAIRO_CONTENT_ALPHA) {
  542.         a = color->alpha;
  543.     } else {
  544.         a = 1.0;
  545.     }
  546.  
  547.     glDisable (GL_SCISSOR_TEST);
  548.     glClearColor (r, g, b, a);
  549.     glClear (GL_COLOR_BUFFER_BIT);
  550.  
  551.     if (a == 0)
  552.         surface->base.is_clear = TRUE;
  553.  
  554.     return _cairo_gl_context_release (ctx, status);
  555. }
  556.  
  557. static cairo_surface_t *
  558. _cairo_gl_surface_create_and_clear_scratch (cairo_gl_context_t *ctx,
  559.                                             cairo_content_t content,
  560.                                             int width,
  561.                                             int height)
  562. {
  563.     cairo_gl_surface_t *surface;
  564.     cairo_int_status_t status;
  565.  
  566.     surface = (cairo_gl_surface_t *)
  567.         _cairo_gl_surface_create_scratch (ctx, content, width, height);
  568.     if (unlikely (surface->base.status))
  569.         return &surface->base;
  570.  
  571.     /* Cairo surfaces start out initialized to transparent (black) */
  572.     status = _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
  573.     if (unlikely (status)) {
  574.         cairo_surface_destroy (&surface->base);
  575.         return _cairo_surface_create_in_error (status);
  576.     }
  577.  
  578.     return &surface->base;
  579. }
  580.  
  581. cairo_surface_t *
  582. cairo_gl_surface_create (cairo_device_t         *abstract_device,
  583.                          cairo_content_t         content,
  584.                          int                     width,
  585.                          int                     height)
  586. {
  587.     cairo_gl_context_t *ctx;
  588.     cairo_gl_surface_t *surface;
  589.     cairo_status_t status;
  590.  
  591.     if (! CAIRO_CONTENT_VALID (content))
  592.         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
  593.  
  594.     if (abstract_device == NULL)
  595.         return _cairo_image_surface_create_with_content (content, width, height);
  596.  
  597.     if (abstract_device->status)
  598.         return _cairo_surface_create_in_error (abstract_device->status);
  599.  
  600.     if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL)
  601.         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
  602.  
  603.     status = _cairo_gl_context_acquire (abstract_device, &ctx);
  604.     if (unlikely (status))
  605.         return _cairo_surface_create_in_error (status);
  606.  
  607.     if (! _cairo_gl_surface_size_valid_for_context (ctx, width, height)) {
  608.         status = _cairo_gl_context_release (ctx, status);
  609.         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
  610.     }
  611.  
  612.     surface = (cairo_gl_surface_t *)
  613.         _cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height);
  614.     if (unlikely (surface->base.status)) {
  615.         status = _cairo_gl_context_release (ctx, surface->base.status);
  616.         cairo_surface_destroy (&surface->base);
  617.         return _cairo_surface_create_in_error (status);
  618.     }
  619.  
  620.     status = _cairo_gl_context_release (ctx, status);
  621.     if (unlikely (status)) {
  622.         cairo_surface_destroy (&surface->base);
  623.         return _cairo_surface_create_in_error (status);
  624.     }
  625.  
  626.     return &surface->base;
  627. }
  628. slim_hidden_def (cairo_gl_surface_create);
  629.  
  630. /**
  631.  * cairo_gl_surface_create_for_texture:
  632.  * @content: type of content in the surface
  633.  * @tex: name of texture to use for storage of surface pixels
  634.  * @width: width of the surface, in pixels
  635.  * @height: height of the surface, in pixels
  636.  *
  637.  * Creates a GL surface for the specified texture with the specified
  638.  * content and dimensions.  The texture must be kept around until the
  639.  * #cairo_surface_t is destroyed or cairo_surface_finish() is called
  640.  * on the surface.  The initial contents of @tex will be used as the
  641.  * initial image contents; you must explicitly clear the buffer,
  642.  * using, for example, cairo_rectangle() and cairo_fill() if you want
  643.  * it cleared.  The format of @tex should be compatible with @content,
  644.  * in the sense that it must have the color components required by
  645.  * @content.
  646.  *
  647.  * Return value: a pointer to the newly created surface. The caller
  648.  * owns the surface and should call cairo_surface_destroy() when done
  649.  * with it.
  650.  *
  651.  * This function always returns a valid pointer, but it will return a
  652.  * pointer to a "nil" surface if an error such as out of memory
  653.  * occurs. You can use cairo_surface_status() to check for this.
  654.  *
  655.  * Since: TBD
  656.  **/
  657. cairo_surface_t *
  658. cairo_gl_surface_create_for_texture (cairo_device_t     *abstract_device,
  659.                                      cairo_content_t     content,
  660.                                      unsigned int        tex,
  661.                                      int                 width,
  662.                                      int                 height)
  663. {
  664.     cairo_gl_context_t *ctx;
  665.     cairo_gl_surface_t *surface;
  666.     cairo_status_t status;
  667.  
  668.     if (! CAIRO_CONTENT_VALID (content))
  669.         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
  670.  
  671.     if (abstract_device == NULL)
  672.         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
  673.  
  674.     if (abstract_device->status)
  675.         return _cairo_surface_create_in_error (abstract_device->status);
  676.  
  677.     if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL)
  678.         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH));
  679.  
  680.     status = _cairo_gl_context_acquire (abstract_device, &ctx);
  681.     if (unlikely (status))
  682.         return _cairo_surface_create_in_error (status);
  683.  
  684.     surface = (cairo_gl_surface_t *)
  685.         _cairo_gl_surface_create_scratch_for_texture (ctx, content,
  686.                                                       tex, width, height);
  687.     status = _cairo_gl_context_release (ctx, status);
  688.  
  689.     return &surface->base;
  690. }
  691. slim_hidden_def (cairo_gl_surface_create_for_texture);
  692.  
  693.  
  694. void
  695. cairo_gl_surface_set_size (cairo_surface_t *abstract_surface,
  696.                            int              width,
  697.                            int              height)
  698. {
  699.     cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
  700.  
  701.     if (unlikely (abstract_surface->status))
  702.         return;
  703.     if (unlikely (abstract_surface->finished)) {
  704.         _cairo_surface_set_error (abstract_surface,
  705.                                   _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  706.         return;
  707.     }
  708.  
  709.     if (! _cairo_surface_is_gl (abstract_surface) ||
  710.         _cairo_gl_surface_is_texture (surface)) {
  711.         _cairo_surface_set_error (abstract_surface,
  712.                                   _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
  713.         return;
  714.     }
  715.  
  716.     if (surface->width != width || surface->height != height) {
  717.         surface->needs_update = TRUE;
  718.         surface->width = width;
  719.         surface->height = height;
  720.     }
  721. }
  722.  
  723. int
  724. cairo_gl_surface_get_width (cairo_surface_t *abstract_surface)
  725. {
  726.     cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
  727.  
  728.     if (! _cairo_surface_is_gl (abstract_surface))
  729.         return 0;
  730.  
  731.     return surface->width;
  732. }
  733.  
  734. int
  735. cairo_gl_surface_get_height (cairo_surface_t *abstract_surface)
  736. {
  737.     cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
  738.  
  739.     if (! _cairo_surface_is_gl (abstract_surface))
  740.         return 0;
  741.  
  742.     return surface->height;
  743. }
  744.  
  745. void
  746. cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
  747. {
  748.     cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface;
  749.  
  750.     if (unlikely (abstract_surface->status))
  751.         return;
  752.     if (unlikely (abstract_surface->finished)) {
  753.         _cairo_surface_set_error (abstract_surface,
  754.                                   _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
  755.         return;
  756.     }
  757.  
  758.     if (! _cairo_surface_is_gl (abstract_surface)) {
  759.         _cairo_surface_set_error (abstract_surface,
  760.                                   CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
  761.         return;
  762.     }
  763.  
  764.     if (! _cairo_gl_surface_is_texture (surface)) {
  765.         cairo_gl_context_t *ctx;
  766.         cairo_status_t status;
  767.  
  768.         status = _cairo_gl_context_acquire (surface->base.device, &ctx);
  769.         if (unlikely (status))
  770.             return;
  771.  
  772.         /* For swapping on EGL, at least, we need a valid context/target. */
  773.         _cairo_gl_context_set_destination (ctx, surface, FALSE);
  774.         /* And in any case we should flush any pending operations. */
  775.         _cairo_gl_composite_flush (ctx);
  776.  
  777.         ctx->swap_buffers (ctx, surface);
  778.  
  779.         status = _cairo_gl_context_release (ctx, status);
  780.         if (status)
  781.             status = _cairo_surface_set_error (abstract_surface, status);
  782.     }
  783. }
  784.  
  785. static cairo_surface_t *
  786. _cairo_gl_surface_create_similar (void           *abstract_surface,
  787.                                   cairo_content_t  content,
  788.                                   int             width,
  789.                                   int             height)
  790. {
  791.     cairo_surface_t *surface = abstract_surface;
  792.     cairo_gl_context_t *ctx;
  793.     cairo_status_t status;
  794.  
  795.     if (! _cairo_gl_surface_size_valid (abstract_surface, width, height))
  796.         return _cairo_image_surface_create_with_content (content, width, height);
  797.  
  798.     status = _cairo_gl_context_acquire (surface->device, &ctx);
  799.     if (unlikely (status))
  800.         return _cairo_surface_create_in_error (status);
  801.  
  802.     surface = _cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height);
  803.  
  804.     status = _cairo_gl_context_release (ctx, status);
  805.     if (unlikely (status)) {
  806.         cairo_surface_destroy (surface);
  807.         return _cairo_surface_create_in_error (status);
  808.     }
  809.  
  810.     return surface;
  811. }
  812.  
  813. static cairo_int_status_t
  814. _cairo_gl_surface_fill_alpha_channel (cairo_gl_surface_t *dst,
  815.                                       cairo_gl_context_t *ctx,
  816.                                       int x, int y,
  817.                                       int width, int height)
  818. {
  819.     cairo_gl_composite_t setup;
  820.     cairo_status_t status;
  821.  
  822.     _cairo_gl_composite_flush (ctx);
  823.     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
  824.  
  825.     status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_SOURCE,
  826.                                        dst, FALSE);
  827.     if (unlikely (status))
  828.         goto CLEANUP;
  829.  
  830.     _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_BLACK);
  831.  
  832.     status = _cairo_gl_composite_begin (&setup, &ctx);
  833.     if (unlikely (status))
  834.         goto CLEANUP;
  835.  
  836.     _cairo_gl_context_emit_rect (ctx, x, y, x + width, y + height);
  837.  
  838.     status = _cairo_gl_context_release (ctx, status);
  839.  
  840.   CLEANUP:
  841.     _cairo_gl_composite_fini (&setup);
  842.  
  843.     _cairo_gl_composite_flush (ctx);
  844.     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  845.  
  846.     return status;
  847. }
  848.  
  849. cairo_status_t
  850. _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
  851.                               cairo_image_surface_t *src,
  852.                               int src_x, int src_y,
  853.                               int width, int height,
  854.                               int dst_x, int dst_y,
  855.                               cairo_bool_t force_flush)
  856. {
  857.     GLenum internal_format, format, type;
  858.     cairo_bool_t has_alpha, needs_swap;
  859.     cairo_image_surface_t *clone = NULL;
  860.     cairo_gl_context_t *ctx;
  861.     int cpp;
  862.     cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
  863.  
  864.     status = _cairo_gl_context_acquire (dst->base.device, &ctx);
  865.     if (unlikely (status))
  866.         return status;
  867.  
  868.     if (! _cairo_gl_get_image_format_and_type (ctx->gl_flavor,
  869.                                                src->pixman_format,
  870.                                                &internal_format,
  871.                                                &format,
  872.                                                &type,
  873.                                                &has_alpha,
  874.                                                &needs_swap))
  875.     {
  876.         cairo_bool_t is_supported;
  877.  
  878.         clone = _cairo_image_surface_coerce (src);
  879.         if (unlikely (status = clone->base.status))
  880.             goto FAIL;
  881.  
  882.         is_supported =
  883.             _cairo_gl_get_image_format_and_type (ctx->gl_flavor,
  884.                                                  clone->pixman_format,
  885.                                                  &internal_format,
  886.                                                  &format,
  887.                                                  &type,
  888.                                                  &has_alpha,
  889.                                                  &needs_swap);
  890.         assert (is_supported);
  891.         assert (!needs_swap);
  892.         src = clone;
  893.     }
  894.  
  895.     cpp = PIXMAN_FORMAT_BPP (src->pixman_format) / 8;
  896.  
  897.     if (force_flush) {
  898.         status = _cairo_gl_surface_flush (&dst->base, 0);
  899.         if (unlikely (status))
  900.             goto FAIL;
  901.     }
  902.  
  903.     if (_cairo_gl_surface_is_texture (dst)) {
  904.         void *data_start = src->data + src_y * src->stride + src_x * cpp;
  905.         void *data_start_gles2 = NULL;
  906.  
  907.         /*
  908.          * Due to GL_UNPACK_ROW_LENGTH missing in GLES2 we have to extract the
  909.          * image data ourselves in some cases. In particular, we must extract
  910.          * the pixels if:
  911.          * a. we don't want full-length lines or
  912.          * b. the row stride cannot be handled by GL itself using a 4 byte
  913.          *     alignment constraint
  914.          */
  915.         if (src->stride < 0 ||
  916.             (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
  917.              (src->width * cpp < src->stride - 3 ||
  918.               width != src->width)))
  919.         {
  920.             glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
  921.             status = _cairo_gl_surface_extract_image_data (src, src_x, src_y,
  922.                                                            width, height,
  923.                                                            &data_start_gles2);
  924.             if (unlikely (status))
  925.                 goto FAIL;
  926.  
  927.             data_start = data_start_gles2;
  928.         }
  929.         else
  930.         {
  931.             glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
  932.             if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
  933.                 glPixelStorei (GL_UNPACK_ROW_LENGTH, src->stride / cpp);
  934.         }
  935.  
  936.         _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
  937.         glBindTexture (ctx->tex_target, dst->tex);
  938.         glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  939.         glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  940.         glTexSubImage2D (ctx->tex_target, 0,
  941.                          dst_x, dst_y, width, height,
  942.                          format, type, data_start);
  943.  
  944.         free (data_start_gles2);
  945.  
  946.         /* If we just treated some rgb-only data as rgba, then we have to
  947.          * go back and fix up the alpha channel where we filled in this
  948.          * texture data.
  949.          */
  950.         if (!has_alpha) {
  951.             _cairo_gl_surface_fill_alpha_channel (dst, ctx,
  952.                                                   dst_x, dst_y,
  953.                                                   width, height);
  954.         }
  955.     } else {
  956.         cairo_surface_t *tmp;
  957.  
  958.         tmp = _cairo_gl_surface_create_scratch (ctx,
  959.                                                 dst->base.content,
  960.                                                 width, height);
  961.         if (unlikely (tmp->status))
  962.             goto FAIL;
  963.  
  964.         status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *) tmp,
  965.                                                src,
  966.                                                src_x, src_y,
  967.                                                width, height,
  968.                                                0, 0, force_flush);
  969.         if (status == CAIRO_INT_STATUS_SUCCESS) {
  970.             cairo_surface_pattern_t tmp_pattern;
  971.             cairo_rectangle_int_t r;
  972.             cairo_clip_t *clip;
  973.  
  974.             _cairo_pattern_init_for_surface (&tmp_pattern, tmp);
  975.             cairo_matrix_init_translate (&tmp_pattern.base.matrix,
  976.                                          -dst_x, -dst_y);
  977.             tmp_pattern.base.filter = CAIRO_FILTER_NEAREST;
  978.             tmp_pattern.base.extend = CAIRO_EXTEND_NONE;
  979.  
  980.             r.x = dst_x;
  981.             r.y = dst_y;
  982.             r.width = width;
  983.             r.height = height;
  984.             clip = _cairo_clip_intersect_rectangle (NULL, &r);
  985.             status = _cairo_surface_paint (&dst->base,
  986.                                            CAIRO_OPERATOR_SOURCE,
  987.                                            &tmp_pattern.base,
  988.                                            clip);
  989.             _cairo_clip_destroy (clip);
  990.             _cairo_pattern_fini (&tmp_pattern.base);
  991.         }
  992.  
  993.         cairo_surface_destroy (tmp);
  994.     }
  995.  
  996. FAIL:
  997.     status = _cairo_gl_context_release (ctx, status);
  998.  
  999.     if (clone)
  1000.         cairo_surface_destroy (&clone->base);
  1001.  
  1002.     return status;
  1003. }
  1004.  
  1005. static int _cairo_gl_surface_flavor (cairo_gl_surface_t *surface)
  1006. {
  1007.     cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
  1008.     return ctx->gl_flavor;
  1009. }
  1010.  
  1011. static cairo_status_t
  1012. _cairo_gl_surface_finish (void *abstract_surface)
  1013. {
  1014.     cairo_gl_surface_t *surface = abstract_surface;
  1015.     cairo_status_t status;
  1016.     cairo_gl_context_t *ctx;
  1017.  
  1018.     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
  1019.     if (unlikely (status))
  1020.         return status;
  1021.  
  1022.     if (ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE &&
  1023.         ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface)
  1024.         _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_SOURCE);
  1025.     if (ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE &&
  1026.         ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface)
  1027.         _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK);
  1028.     if (ctx->current_target == surface)
  1029.         ctx->current_target = NULL;
  1030.  
  1031.     if (surface->fb)
  1032.         ctx->dispatch.DeleteFramebuffers (1, &surface->fb);
  1033.     if (surface->depth_stencil)
  1034.         ctx->dispatch.DeleteRenderbuffers (1, &surface->depth_stencil);
  1035.     if (surface->owns_tex)
  1036.         glDeleteTextures (1, &surface->tex);
  1037.  
  1038.     if (surface->msaa_depth_stencil)
  1039.         ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_depth_stencil);
  1040.  
  1041. #if CAIRO_HAS_GL_SURFACE
  1042.     if (surface->msaa_fb)
  1043.         ctx->dispatch.DeleteFramebuffers (1, &surface->msaa_fb);
  1044.     if (surface->msaa_rb)
  1045.         ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_rb);
  1046. #endif
  1047.  
  1048.     _cairo_clip_destroy (surface->clip_on_stencil_buffer);
  1049.  
  1050.     return _cairo_gl_context_release (ctx, status);
  1051. }
  1052.  
  1053. static cairo_image_surface_t *
  1054. _cairo_gl_surface_map_to_image (void      *abstract_surface,
  1055.                                 const cairo_rectangle_int_t   *extents)
  1056. {
  1057.     cairo_gl_surface_t *surface = abstract_surface;
  1058.     cairo_image_surface_t *image;
  1059.     cairo_gl_context_t *ctx;
  1060.     GLenum format, type;
  1061.     pixman_format_code_t pixman_format;
  1062.     unsigned int cpp;
  1063.     cairo_bool_t flipped, mesa_invert;
  1064.     cairo_status_t status;
  1065.     int y;
  1066.  
  1067.     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
  1068.     if (unlikely (status)) {
  1069.         return _cairo_image_surface_create_in_error (status);
  1070.     }
  1071.  
  1072.     /* Want to use a switch statement here but the compiler gets whiny. */
  1073.     if (surface->base.content == CAIRO_CONTENT_COLOR_ALPHA) {
  1074.         format = GL_BGRA;
  1075.         pixman_format = PIXMAN_a8r8g8b8;
  1076.         type = GL_UNSIGNED_INT_8_8_8_8_REV;
  1077.         cpp = 4;
  1078.     } else if (surface->base.content == CAIRO_CONTENT_COLOR) {
  1079.         format = GL_BGRA;
  1080.         pixman_format = PIXMAN_x8r8g8b8;
  1081.         type = GL_UNSIGNED_INT_8_8_8_8_REV;
  1082.         cpp = 4;
  1083.     } else if (surface->base.content == CAIRO_CONTENT_ALPHA) {
  1084.         format = GL_ALPHA;
  1085.         pixman_format = PIXMAN_a8;
  1086.         type = GL_UNSIGNED_BYTE;
  1087.         cpp = 1;
  1088.     } else {
  1089.         ASSERT_NOT_REACHED;
  1090.         return NULL;
  1091.     }
  1092.  
  1093.     if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES) {
  1094.         /* If only RGBA is supported, we must download data in a compatible
  1095.          * format. This means that pixman will convert the data on the CPU when
  1096.          * interacting with other image surfaces. For ALPHA, GLES2 does not
  1097.          * support GL_PACK_ROW_LENGTH anyway, and this makes sure that the
  1098.          * pixman image that is created has row_stride = row_width * bpp. */
  1099.         if (surface->base.content == CAIRO_CONTENT_ALPHA || !ctx->can_read_bgra) {
  1100.             cairo_bool_t little_endian = _cairo_is_little_endian ();
  1101.             format = GL_RGBA;
  1102.  
  1103.             if (surface->base.content == CAIRO_CONTENT_COLOR) {
  1104.                 pixman_format = little_endian ?
  1105.                     PIXMAN_x8b8g8r8 : PIXMAN_r8g8b8x8;
  1106.             } else {
  1107.                 pixman_format = little_endian ?
  1108.                     PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8;
  1109.             }
  1110.         }
  1111.  
  1112.         /* GLES2 only supports GL_UNSIGNED_BYTE. */
  1113.         type = GL_UNSIGNED_BYTE;
  1114.         cpp = 4;
  1115.     }
  1116.  
  1117.     image = (cairo_image_surface_t*)
  1118.         _cairo_image_surface_create_with_pixman_format (NULL,
  1119.                                                         pixman_format,
  1120.                                                         extents->width,
  1121.                                                         extents->height,
  1122.                                                         -1);
  1123.     if (unlikely (image->base.status)) {
  1124.         status = _cairo_gl_context_release (ctx, status);
  1125.         return image;
  1126.     }
  1127.  
  1128.     cairo_surface_set_device_offset (&image->base, -extents->x, -extents->y);
  1129.  
  1130.     /* If the original surface has not been modified or
  1131.      * is clear, we can avoid downloading data. */
  1132.     if (surface->base.is_clear || surface->base.serial == 0) {
  1133.         status = _cairo_gl_context_release (ctx, status);
  1134.         return image;
  1135.     }
  1136.  
  1137.     /* This is inefficient, as we'd rather just read the thing without making
  1138.      * it the destination.  But then, this is the fallback path, so let's not
  1139.      * fall back instead.
  1140.      */
  1141.     _cairo_gl_composite_flush (ctx);
  1142.     _cairo_gl_context_set_destination (ctx, surface, FALSE);
  1143.  
  1144.     flipped = ! _cairo_gl_surface_is_texture (surface);
  1145.     mesa_invert = flipped && ctx->has_mesa_pack_invert;
  1146.  
  1147.     glPixelStorei (GL_PACK_ALIGNMENT, 4);
  1148.     if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
  1149.         glPixelStorei (GL_PACK_ROW_LENGTH, image->stride / cpp);
  1150.     if (mesa_invert)
  1151.         glPixelStorei (GL_PACK_INVERT_MESA, 1);
  1152.  
  1153.     y = extents->y;
  1154.     if (flipped)
  1155.         y = surface->height - extents->y - extents->height;
  1156.  
  1157.     glReadPixels (extents->x, y,
  1158.                   extents->width, extents->height,
  1159.                   format, type, image->data);
  1160.     if (mesa_invert)
  1161.         glPixelStorei (GL_PACK_INVERT_MESA, 0);
  1162.  
  1163.     status = _cairo_gl_context_release (ctx, status);
  1164.     if (unlikely (status)) {
  1165.         cairo_surface_destroy (&image->base);
  1166.         return _cairo_image_surface_create_in_error (status);
  1167.     }
  1168.  
  1169.     /* We must invert the image manualy if we lack GL_MESA_pack_invert */
  1170.     if (flipped && ! mesa_invert) {
  1171.         uint8_t stack[1024], *row = stack;
  1172.         uint8_t *top = image->data;
  1173.         uint8_t *bot = image->data + (image->height-1)*image->stride;
  1174.  
  1175.         if (image->stride > (int)sizeof(stack)) {
  1176.             row = malloc (image->stride);
  1177.             if (unlikely (row == NULL)) {
  1178.                 cairo_surface_destroy (&image->base);
  1179.                 return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
  1180.             }
  1181.         }
  1182.  
  1183.         while (top < bot) {
  1184.             memcpy (row, top, image->stride);
  1185.             memcpy (top, bot, image->stride);
  1186.             memcpy (bot, row, image->stride);
  1187.             top += image->stride;
  1188.             bot -= image->stride;
  1189.         }
  1190.  
  1191.         if (row != stack)
  1192.             free(row);
  1193.     }
  1194.  
  1195.     image->base.is_clear = FALSE;
  1196.     return image;
  1197. }
  1198.  
  1199. static cairo_surface_t *
  1200. _cairo_gl_surface_source (void                 *abstract_surface,
  1201.                           cairo_rectangle_int_t *extents)
  1202. {
  1203.     cairo_gl_surface_t *surface = abstract_surface;
  1204.  
  1205.     if (extents) {
  1206.         extents->x = extents->y = 0;
  1207.         extents->width  = surface->width;
  1208.         extents->height = surface->height;
  1209.     }
  1210.  
  1211.     return &surface->base;
  1212. }
  1213.  
  1214. static cairo_status_t
  1215. _cairo_gl_surface_acquire_source_image (void                   *abstract_surface,
  1216.                                         cairo_image_surface_t **image_out,
  1217.                                         void                  **image_extra)
  1218. {
  1219.     cairo_gl_surface_t *surface = abstract_surface;
  1220.     cairo_rectangle_int_t extents;
  1221.  
  1222.     *image_extra = NULL;
  1223.  
  1224.     extents.x = extents.y = 0;
  1225.     extents.width = surface->width;
  1226.     extents.height = surface->height;
  1227.  
  1228.     *image_out = (cairo_image_surface_t *)
  1229.         _cairo_gl_surface_map_to_image (surface, &extents);
  1230.     return (*image_out)->base.status;
  1231. }
  1232.  
  1233. static void
  1234. _cairo_gl_surface_release_source_image (void                  *abstract_surface,
  1235.                                         cairo_image_surface_t *image,
  1236.                                         void                  *image_extra)
  1237. {
  1238.     cairo_surface_destroy (&image->base);
  1239. }
  1240.  
  1241. static cairo_int_status_t
  1242. _cairo_gl_surface_unmap_image (void                   *abstract_surface,
  1243.                                cairo_image_surface_t *image)
  1244. {
  1245.     cairo_int_status_t status;
  1246.  
  1247.     status = _cairo_gl_surface_draw_image (abstract_surface, image,
  1248.                                            0, 0,
  1249.                                            image->width, image->height,
  1250.                                            image->base.device_transform_inverse.x0,
  1251.                                            image->base.device_transform_inverse.y0,
  1252.                                            TRUE);
  1253.  
  1254.     cairo_surface_finish (&image->base);
  1255.     cairo_surface_destroy (&image->base);
  1256.  
  1257.     return status;
  1258. }
  1259.  
  1260. static cairo_bool_t
  1261. _cairo_gl_surface_get_extents (void                  *abstract_surface,
  1262.                                cairo_rectangle_int_t *rectangle)
  1263. {
  1264.     cairo_gl_surface_t *surface = abstract_surface;
  1265.  
  1266.     rectangle->x = 0;
  1267.     rectangle->y = 0;
  1268.     rectangle->width  = surface->width;
  1269.     rectangle->height = surface->height;
  1270.  
  1271.     return TRUE;
  1272. }
  1273.  
  1274. static cairo_status_t
  1275. _cairo_gl_surface_flush (void *abstract_surface, unsigned flags)
  1276. {
  1277.     cairo_gl_surface_t *surface = abstract_surface;
  1278.     cairo_status_t status;
  1279.     cairo_gl_context_t *ctx;
  1280.  
  1281.     if (flags)
  1282.         return CAIRO_STATUS_SUCCESS;
  1283.  
  1284.     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
  1285.     if (unlikely (status))
  1286.         return status;
  1287.  
  1288.     if ((ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE &&
  1289.          ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface) ||
  1290.         (ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE &&
  1291.          ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface) ||
  1292.         (ctx->current_target == surface))
  1293.       _cairo_gl_composite_flush (ctx);
  1294.  
  1295.     status = _cairo_gl_surface_resolve_multisampling (surface);
  1296.  
  1297.     return _cairo_gl_context_release (ctx, status);
  1298. }
  1299.  
  1300. cairo_int_status_t
  1301. _cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface)
  1302. {
  1303.     cairo_gl_context_t *ctx;
  1304.     cairo_int_status_t status;
  1305.  
  1306.     if (! surface->msaa_active)
  1307.         return CAIRO_INT_STATUS_SUCCESS;
  1308.  
  1309.     if (surface->base.device == NULL)
  1310.         return CAIRO_INT_STATUS_SUCCESS;
  1311.  
  1312.     /* GLES surfaces do not need explicit resolution. */
  1313.     if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES)
  1314.         return CAIRO_INT_STATUS_SUCCESS;
  1315.  
  1316.     if (! _cairo_gl_surface_is_texture (surface))
  1317.         return CAIRO_INT_STATUS_SUCCESS;
  1318.  
  1319.     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
  1320.     if (unlikely (status))
  1321.         return status;
  1322.  
  1323.     ctx->current_target = surface;
  1324.  
  1325. #if CAIRO_HAS_GL_SURFACE
  1326.     _cairo_gl_context_bind_framebuffer (ctx, surface, FALSE);
  1327. #endif
  1328.  
  1329.     status = _cairo_gl_context_release (ctx, status);
  1330.     return status;
  1331. }
  1332.  
  1333. static const cairo_compositor_t *
  1334. get_compositor (cairo_gl_surface_t *surface)
  1335. {
  1336.     cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device;
  1337.     return ctx->compositor;
  1338. }
  1339.  
  1340. static cairo_int_status_t
  1341. _cairo_gl_surface_paint (void                   *surface,
  1342.                          cairo_operator_t        op,
  1343.                          const cairo_pattern_t  *source,
  1344.                          const cairo_clip_t     *clip)
  1345. {
  1346.     /* simplify the common case of clearing the surface */
  1347.     if (clip == NULL) {
  1348.         if (op == CAIRO_OPERATOR_CLEAR)
  1349.             return _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
  1350.        else if (source->type == CAIRO_PATTERN_TYPE_SOLID &&
  1351.                 (op == CAIRO_OPERATOR_SOURCE ||
  1352.                  (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_opaque_solid (source)))) {
  1353.             return _cairo_gl_surface_clear (surface,
  1354.                                             &((cairo_solid_pattern_t *) source)->color);
  1355.         }
  1356.     }
  1357.  
  1358.     return _cairo_compositor_paint (get_compositor (surface), surface,
  1359.                                     op, source, clip);
  1360. }
  1361.  
  1362. static cairo_int_status_t
  1363. _cairo_gl_surface_mask (void                     *surface,
  1364.                         cairo_operator_t          op,
  1365.                         const cairo_pattern_t   *source,
  1366.                         const cairo_pattern_t   *mask,
  1367.                         const cairo_clip_t      *clip)
  1368. {
  1369.     return _cairo_compositor_mask (get_compositor (surface), surface,
  1370.                                    op, source, mask, clip);
  1371. }
  1372.  
  1373. static cairo_int_status_t
  1374. _cairo_gl_surface_stroke (void                          *surface,
  1375.                           cairo_operator_t               op,
  1376.                           const cairo_pattern_t         *source,
  1377.                           const cairo_path_fixed_t      *path,
  1378.                           const cairo_stroke_style_t    *style,
  1379.                           const cairo_matrix_t          *ctm,
  1380.                           const cairo_matrix_t          *ctm_inverse,
  1381.                           double                         tolerance,
  1382.                           cairo_antialias_t              antialias,
  1383.                           const cairo_clip_t            *clip)
  1384. {
  1385.     return _cairo_compositor_stroke (get_compositor (surface), surface,
  1386.                                      op, source, path, style,
  1387.                                      ctm, ctm_inverse, tolerance, antialias,
  1388.                                      clip);
  1389. }
  1390.  
  1391. static cairo_int_status_t
  1392. _cairo_gl_surface_fill (void                    *surface,
  1393.                         cairo_operator_t         op,
  1394.                         const cairo_pattern_t   *source,
  1395.                         const cairo_path_fixed_t*path,
  1396.                         cairo_fill_rule_t        fill_rule,
  1397.                         double                   tolerance,
  1398.                         cairo_antialias_t        antialias,
  1399.                         const cairo_clip_t      *clip)
  1400. {
  1401.     return _cairo_compositor_fill (get_compositor (surface), surface,
  1402.                                    op, source, path,
  1403.                                    fill_rule, tolerance, antialias,
  1404.                                    clip);
  1405. }
  1406.  
  1407. static cairo_int_status_t
  1408. _cairo_gl_surface_glyphs (void                  *surface,
  1409.                           cairo_operator_t       op,
  1410.                           const cairo_pattern_t *source,
  1411.                           cairo_glyph_t         *glyphs,
  1412.                           int                    num_glyphs,
  1413.                           cairo_scaled_font_t   *font,
  1414.                           const cairo_clip_t    *clip)
  1415. {
  1416.     return _cairo_compositor_glyphs (get_compositor (surface), surface,
  1417.                                      op, source, glyphs, num_glyphs, font,
  1418.                                      clip);
  1419. }
  1420.  
  1421. static const cairo_surface_backend_t _cairo_gl_surface_backend = {
  1422.     CAIRO_SURFACE_TYPE_GL,
  1423.     _cairo_gl_surface_finish,
  1424.     _cairo_default_context_create,
  1425.  
  1426.     _cairo_gl_surface_create_similar,
  1427.     NULL, /* similar image */
  1428.     _cairo_gl_surface_map_to_image,
  1429.     _cairo_gl_surface_unmap_image,
  1430.  
  1431.     _cairo_gl_surface_source,
  1432.     _cairo_gl_surface_acquire_source_image,
  1433.     _cairo_gl_surface_release_source_image,
  1434.     NULL, /* snapshot */
  1435.  
  1436.     NULL, /* copy_page */
  1437.     NULL, /* show_page */
  1438.  
  1439.     _cairo_gl_surface_get_extents,
  1440.     _cairo_image_surface_get_font_options,
  1441.  
  1442.     _cairo_gl_surface_flush,
  1443.     NULL, /* mark_dirty_rectangle */
  1444.  
  1445.     _cairo_gl_surface_paint,
  1446.     _cairo_gl_surface_mask,
  1447.     _cairo_gl_surface_stroke,
  1448.     _cairo_gl_surface_fill,
  1449.     NULL, /* fill/stroke */
  1450.     _cairo_gl_surface_glyphs,
  1451. };
  1452.