gfx/thebes/gfxAlphaRecovery.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial