LCOV - code coverage report
Current view: top level - gfx/cairo/cairo/src - cairo-surface-snapshot.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 84 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* cairo - a vector graphics library with display and print output
       2             :  *
       3             :  * Copyright © 2002 University of Southern California
       4             :  * Copyright © 2005 Red Hat, Inc.
       5             :  * Copyright © 2009 Intel Corporation
       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 University of Southern
      33             :  * California.
      34             :  *
      35             :  * Contributor(s):
      36             :  *      Carl D. Worth <cworth@cworth.org>
      37             :  *      Chris Wilson <chris@chris-wilson.co.uk>
      38             :  */
      39             : 
      40             : #include "cairoint.h"
      41             : 
      42             : #include "cairo-error-private.h"
      43             : #include "cairo-surface-snapshot-private.h"
      44             : 
      45             : static cairo_status_t
      46           0 : _cairo_surface_snapshot_finish (void *abstract_surface)
      47             : {
      48           0 :     cairo_surface_snapshot_t *surface = abstract_surface;
      49           0 :     cairo_status_t status = CAIRO_STATUS_SUCCESS;
      50             : 
      51           0 :     if (surface->clone != NULL) {
      52           0 :         cairo_surface_finish (surface->clone);
      53           0 :         status = surface->clone->status;
      54             : 
      55           0 :         cairo_surface_destroy (surface->clone);
      56             :     }
      57             : 
      58           0 :     return status;
      59             : }
      60             : 
      61             : static cairo_status_t
      62           0 : _cairo_surface_snapshot_acquire_source_image (void                    *abstract_surface,
      63             :                                               cairo_image_surface_t  **image_out,
      64             :                                               void                   **extra_out)
      65             : {
      66           0 :     cairo_surface_snapshot_t *surface = abstract_surface;
      67             : 
      68           0 :     return _cairo_surface_acquire_source_image (surface->target, image_out, extra_out);
      69             : }
      70             : 
      71             : static void
      72           0 : _cairo_surface_snapshot_release_source_image (void                   *abstract_surface,
      73             :                                               cairo_image_surface_t  *image,
      74             :                                               void                   *extra)
      75             : {
      76           0 :     cairo_surface_snapshot_t *surface = abstract_surface;
      77             : 
      78           0 :     _cairo_surface_release_source_image (surface->target, image, extra);
      79           0 : }
      80             : 
      81             : static cairo_bool_t
      82           0 : _cairo_surface_snapshot_get_extents (void                  *abstract_surface,
      83             :                                      cairo_rectangle_int_t *extents)
      84             : {
      85           0 :     cairo_surface_snapshot_t *surface = abstract_surface;
      86             : 
      87           0 :     return _cairo_surface_get_extents (surface->target, extents);
      88             : }
      89             : 
      90             : static const cairo_surface_backend_t _cairo_surface_snapshot_backend = {
      91             :     CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT,
      92             : 
      93             :     NULL, /* create similar */
      94             :     _cairo_surface_snapshot_finish,
      95             : 
      96             :     _cairo_surface_snapshot_acquire_source_image,
      97             :     _cairo_surface_snapshot_release_source_image,
      98             :     NULL, NULL, /* acquire, release dest */
      99             :     NULL, /* clone similar */
     100             :     NULL, /* composite */
     101             :     NULL, /* fill rectangles */
     102             :     NULL, /* composite trapezoids */
     103             :     NULL, /* create span renderer */
     104             :     NULL, /* check span renderer */
     105             :     NULL, /* copy_page */
     106             :     NULL, /* show_page */
     107             :     _cairo_surface_snapshot_get_extents,
     108             : };
     109             : 
     110             : static void
     111           0 : _cairo_surface_snapshot_copy_on_write (cairo_surface_t *surface)
     112             : {
     113           0 :     cairo_surface_snapshot_t *snapshot = (cairo_surface_snapshot_t *) surface;
     114             :     cairo_image_surface_t *image;
     115             :     cairo_image_surface_t *clone;
     116             :     void *extra;
     117             :     cairo_status_t status;
     118             : 
     119             :     /* We need to make an image copy of the original surface since the
     120             :      * snapshot may exceed the lifetime of the original device, i.e.
     121             :      * when we later need to use the snapshot the data may have already
     122             :      * been lost.
     123             :      */
     124             : 
     125           0 :     status = _cairo_surface_acquire_source_image (snapshot->target, &image, &extra);
     126           0 :     if (unlikely (status)) {
     127           0 :         snapshot->target = _cairo_surface_create_in_error (status);
     128           0 :         status = _cairo_surface_set_error (surface, status);
     129           0 :         return;
     130             :     }
     131             : 
     132           0 :     clone = (cairo_image_surface_t *)
     133           0 :         _cairo_image_surface_create_with_pixman_format (NULL,
     134           0 :                                                         image->pixman_format,
     135           0 :                                                         image->width,
     136           0 :                                                         image->height,
     137             :                                                         0);
     138           0 :     if (likely (clone->base.status == CAIRO_STATUS_SUCCESS)) {
     139           0 :         if (clone->stride == image->stride) {
     140           0 :             memcpy (clone->data, image->data, image->stride * image->height);
     141             :         } else {
     142           0 :             pixman_image_composite32 (PIXMAN_OP_SRC,
     143           0 :                                       image->pixman_image, NULL, clone->pixman_image,
     144             :                                       0, 0,
     145             :                                       0, 0,
     146             :                                       0, 0,
     147           0 :                                       image->width, image->height);
     148             :         }
     149           0 :         clone->base.is_clear = FALSE;
     150             : 
     151           0 :         snapshot->clone = &clone->base;
     152             :     } else {
     153           0 :         snapshot->clone = &clone->base;
     154           0 :         status = _cairo_surface_set_error (surface, clone->base.status);
     155             :     }
     156             : 
     157           0 :     _cairo_surface_release_source_image (snapshot->target, image, extra);
     158           0 :     snapshot->target = snapshot->clone;
     159           0 :     snapshot->base.type = snapshot->target->type;
     160             : }
     161             : 
     162             : /**
     163             :  * _cairo_surface_snapshot
     164             :  * @surface: a #cairo_surface_t
     165             :  *
     166             :  * Make an immutable reference to @surface. It is an error to call a
     167             :  * surface-modifying function on the result of this function. The
     168             :  * resulting 'snapshot' is a lazily copied-on-write surface i.e. it
     169             :  * remains a reference to the original surface until that surface is
     170             :  * written to again, at which time a copy is made of the original surface
     171             :  * and the snapshot then points to that instead. Multiple snapshots of the
     172             :  * same unmodified surface point to the same copy.
     173             :  *
     174             :  * The caller owns the return value and should call
     175             :  * cairo_surface_destroy() when finished with it. This function will not
     176             :  * return %NULL, but will return a nil surface instead.
     177             :  *
     178             :  * Return value: The snapshot surface. Note that the return surface
     179             :  * may not necessarily be of the same type as @surface.
     180             :  **/
     181             : cairo_surface_t *
     182           0 : _cairo_surface_snapshot (cairo_surface_t *surface)
     183             : {
     184             :     cairo_surface_snapshot_t *snapshot;
     185             :     cairo_status_t status;
     186             : 
     187           0 :     if (unlikely (surface->status))
     188           0 :         return _cairo_surface_create_in_error (surface->status);
     189             : 
     190           0 :     if (surface->finished)
     191           0 :         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
     192             : 
     193           0 :     if (surface->snapshot_of != NULL)
     194           0 :         return cairo_surface_reference (surface);
     195             : 
     196           0 :     if (surface->backend->snapshot != NULL) {
     197             :         cairo_surface_t *snap;
     198             : 
     199           0 :         snap = _cairo_surface_has_snapshot (surface, surface->backend);
     200           0 :         if (snap != NULL)
     201           0 :             return cairo_surface_reference (snap);
     202             : 
     203           0 :         snap = surface->backend->snapshot (surface);
     204           0 :         if (snap != NULL) {
     205           0 :             if (unlikely (snap->status))
     206           0 :                 return snap;
     207             : 
     208           0 :             status = _cairo_surface_copy_mime_data (snap, surface);
     209           0 :             if (unlikely (status)) {
     210           0 :                 cairo_surface_destroy (snap);
     211           0 :                 return _cairo_surface_create_in_error (status);
     212             :             }
     213             : 
     214           0 :             snap->device_transform = surface->device_transform;
     215           0 :             snap->device_transform_inverse = surface->device_transform_inverse;
     216             : 
     217           0 :             cairo_surface_attach_snapshot (surface, snap, NULL);
     218             : 
     219           0 :             return snap;
     220             :         }
     221             :     }
     222             : 
     223           0 :     snapshot = (cairo_surface_snapshot_t *)
     224             :         _cairo_surface_has_snapshot (surface, &_cairo_surface_snapshot_backend);
     225           0 :     if (snapshot != NULL)
     226           0 :         return cairo_surface_reference (&snapshot->base);
     227             : 
     228           0 :     snapshot = malloc (sizeof (cairo_surface_snapshot_t));
     229           0 :     if (unlikely (snapshot == NULL))
     230           0 :         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
     231             : 
     232           0 :     _cairo_surface_init (&snapshot->base,
     233             :                          &_cairo_surface_snapshot_backend,
     234             :                          NULL, /* device */
     235             :                          surface->content);
     236           0 :     snapshot->base.type = surface->type;
     237             : 
     238           0 :     snapshot->target = surface;
     239           0 :     snapshot->clone = NULL;
     240             : 
     241           0 :     status = _cairo_surface_copy_mime_data (&snapshot->base, surface);
     242           0 :     if (unlikely (status)) {
     243           0 :         cairo_surface_destroy (&snapshot->base);
     244           0 :         return _cairo_surface_create_in_error (status);
     245             :     }
     246             : 
     247           0 :     snapshot->base.device_transform = surface->device_transform;
     248           0 :     snapshot->base.device_transform_inverse = surface->device_transform_inverse;
     249             : 
     250           0 :     cairo_surface_attach_snapshot (surface,
     251             :                                     &snapshot->base,
     252             :                                     _cairo_surface_snapshot_copy_on_write);
     253             : 
     254           0 :     return &snapshot->base;
     255             : }

Generated by: LCOV version 1.13