LCOV - code coverage report
Current view: top level - gfx/thebes - gfxAlphaRecovery.h (source / functions) Hit Total Coverage
Test: output.info Lines: 1 8 12.5 %
Date: 2017-07-14 16:53:18 Functions: 1 2 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef _GFXALPHARECOVERY_H_
       7             : #define _GFXALPHARECOVERY_H_
       8             : 
       9             : #include "mozilla/SSE.h"
      10             : #include "gfxTypes.h"
      11             : #include "mozilla/gfx/Rect.h"
      12             : 
      13             : class gfxImageSurface;
      14             : 
      15             : class gfxAlphaRecovery {
      16             : public:
      17             :     /**
      18             :      * Some SIMD fast-paths only can be taken if the relative
      19             :      * byte-alignment of images' pointers and strides meets certain
      20             :      * criteria.  Aligning image pointers and strides by
      21             :      * |GoodAlignmentLog2()| below will ensure that fast-paths aren't
      22             :      * skipped because of misalignment.  Fast-paths may still be taken
      23             :      * even if GoodAlignmentLog2() is not met, in some conditions.
      24             :      */
      25          53 :     static uint32_t GoodAlignmentLog2() { return 4; /* for SSE2 */ }
      26             : 
      27             :     /* Given two surfaces of equal size with the same rendering, one onto a
      28             :      * black background and the other onto white, recovers alpha values from
      29             :      * the difference and sets the alpha values on the black surface.
      30             :      * The surfaces must have format RGB24 or ARGB32.
      31             :      * Returns true on success.
      32             :      */
      33             :     static bool RecoverAlpha (gfxImageSurface *blackSurface,
      34             :                                 const gfxImageSurface *whiteSurface);
      35             : 
      36             : #ifdef MOZILLA_MAY_SUPPORT_SSE2
      37             :     /* This does the same as the previous function, but uses SSE2
      38             :      * optimizations. Usually this should not be called directly.  Be sure to
      39             :      * check mozilla::supports_sse2() before calling this function.
      40             :      */
      41             :     static bool RecoverAlphaSSE2 (gfxImageSurface *blackSurface,
      42             :                                     const gfxImageSurface *whiteSurface);
      43             : 
      44             :     /**
      45             :      * A common use-case for alpha recovery is to paint into a
      46             :      * temporary "white image", then paint onto a subrect of the
      47             :      * surface, the "black image", into which alpha-recovered pixels
      48             :      * are eventually to be written.  This function returns a rect
      49             :      * aligned so that recovering alpha for that rect will hit SIMD
      50             :      * fast-paths, if possible.  It's not always possible to align
      51             :      * |aRect| so that fast-paths will be taken.
      52             :      *
      53             :      * The returned rect is always a superset of |aRect|.
      54             :      */
      55             :     static mozilla::gfx::IntRect AlignRectForSubimageRecovery(const mozilla::gfx::IntRect& aRect,
      56             :                                                               gfxImageSurface* aSurface);
      57             : #else
      58             :     static mozilla::gfx::IntRect AlignRectForSubimageRecovery(const mozilla::gfx::IntRect& aRect,
      59             :                                                               gfxImageSurface*)
      60             :     { return aRect; }
      61             : #endif
      62             : 
      63             :     /** from cairo-xlib-utils.c, modified */
      64             :     /**
      65             :      * Given the RGB data for two image surfaces, one a source image composited
      66             :      * with OVER onto a black background, and one a source image composited with 
      67             :      * OVER onto a white background, reconstruct the original image data into
      68             :      * black_data.
      69             :      *
      70             :      * Consider a single color channel and a given pixel. Suppose the original
      71             :      * premultiplied color value was C and the alpha value was A. Let the final
      72             :      * on-black color be B and the final on-white color be W. All values range
      73             :      * over 0-255.
      74             :      *
      75             :      * Then B=C and W=(255*(255 - A) + C*255)/255. Solving for A, we get
      76             :      * A=255 - (W - C). Therefore it suffices to leave the black_data color
      77             :      * data alone and set the alpha values using that simple formula. It shouldn't
      78             :      * matter what color channel we pick for the alpha computation, but we'll
      79             :      * pick green because if we went through a color channel downsample the green
      80             :      * bits are likely to be the most accurate.
      81             :      *
      82             :      * This function needs to be in the header file since it's used by both
      83             :      * gfxRecoverAlpha.cpp and gfxRecoverAlphaSSE2.cpp.
      84             :      */
      85             : 
      86             :     static inline uint32_t
      87           0 :     RecoverPixel(uint32_t black, uint32_t white)
      88             :     {
      89           0 :         const uint32_t GREEN_MASK = 0x0000FF00;
      90           0 :         const uint32_t ALPHA_MASK = 0xFF000000;
      91             : 
      92             :         /* |diff| here is larger when the source image pixel is more transparent.
      93             :            If both renderings are from the same source image composited with OVER,
      94             :            then the color values on white will always be greater than those on
      95             :            black, so |diff| would not overflow.  However, overflow may happen, for
      96             :            example, when a plugin plays a video and the image is rapidly changing.
      97             :            If there is overflow, then behave as if we limit to the difference to
      98             :            >= 0, which will make the rendering opaque.  (Without this overflow
      99             :            will make the rendering transparent.) */
     100           0 :         uint32_t diff = (white & GREEN_MASK) - (black & GREEN_MASK);
     101             :         /* |diff| is 0xFFFFxx00 on overflow and 0x0000xx00 otherwise, so use this
     102             :             to limit the transparency. */
     103           0 :         uint32_t limit = diff & ALPHA_MASK;
     104             :         /* The alpha bits of the result */
     105           0 :         uint32_t alpha = (ALPHA_MASK - (diff << 16)) | limit;
     106             : 
     107           0 :         return alpha | (black & ~ALPHA_MASK);
     108             :     }
     109             : };
     110             : 
     111             : #endif /* _GFXALPHARECOVERY_H_ */

Generated by: LCOV version 1.13