gfx/thebes/gfxUtils.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 GFX_UTILS_H
     7 #define GFX_UTILS_H
     9 #include "gfxTypes.h"
    10 #include "GraphicsFilter.h"
    11 #include "imgIContainer.h"
    12 #include "mozilla/gfx/2D.h"
    13 #include "mozilla/RefPtr.h"
    15 class gfxDrawable;
    16 class nsIntRegion;
    17 struct nsIntRect;
    19 namespace mozilla {
    20 namespace layers {
    21 class PlanarYCbCrData;
    22 }
    23 }
    25 class gfxUtils {
    26 public:
    27     typedef mozilla::gfx::DataSourceSurface DataSourceSurface;
    28     typedef mozilla::gfx::IntPoint IntPoint;
    29     typedef mozilla::gfx::Matrix Matrix;
    30     typedef mozilla::gfx::SourceSurface SourceSurface;
    31     typedef mozilla::gfx::SurfaceFormat SurfaceFormat;
    33     /*
    34      * Premultiply or Unpremultiply aSourceSurface, writing the result
    35      * to aDestSurface or back into aSourceSurface if aDestSurface is null.
    36      *
    37      * If aDestSurface is given, it must have identical format, dimensions, and
    38      * stride as the source.
    39      *
    40      * If the source is not gfxImageFormat::ARGB32, no operation is performed.  If
    41      * aDestSurface is given, the data is copied over.
    42      */
    43     static void PremultiplyImageSurface(gfxImageSurface *aSourceSurface,
    44                                         gfxImageSurface *aDestSurface = nullptr);
    45     static void UnpremultiplyImageSurface(gfxImageSurface *aSurface,
    46                                           gfxImageSurface *aDestSurface = nullptr);
    47     static mozilla::TemporaryRef<DataSourceSurface> UnpremultiplyDataSurface(DataSourceSurface* aSurface);
    49     static void ConvertBGRAtoRGBA(gfxImageSurface *aSourceSurface,
    50                                   gfxImageSurface *aDestSurface = nullptr);
    51     static void ConvertBGRAtoRGBA(uint8_t* aData, uint32_t aLength);
    53     /**
    54      * Draw something drawable while working around limitations like bad support
    55      * for EXTEND_PAD, lack of source-clipping, or cairo / pixman bugs with
    56      * extreme user-space-to-image-space transforms.
    57      *
    58      * The input parameters here usually come from the output of our image
    59      * snapping algorithm in nsLayoutUtils.cpp.
    60      * This method is split from nsLayoutUtils::DrawPixelSnapped to allow for
    61      * adjusting the parameters. For example, certain images with transparent
    62      * margins only have a drawable subimage. For those images, imgFrame::Draw
    63      * will tweak the rects and transforms that it gets from the pixel snapping
    64      * algorithm before passing them on to this method.
    65      */
    66     static void DrawPixelSnapped(gfxContext*      aContext,
    67                                  gfxDrawable*     aDrawable,
    68                                  const gfxMatrix& aUserSpaceToImageSpace,
    69                                  const gfxRect&   aSubimage,
    70                                  const gfxRect&   aSourceRect,
    71                                  const gfxRect&   aImageRect,
    72                                  const gfxRect&   aFill,
    73                                  const gfxImageFormat aFormat,
    74                                  GraphicsFilter aFilter,
    75                                  uint32_t         aImageFlags = imgIContainer::FLAG_NONE);
    77     /**
    78      * Clip aContext to the region aRegion.
    79      */
    80     static void ClipToRegion(gfxContext* aContext, const nsIntRegion& aRegion);
    82     /**
    83      * Clip aTarget to the region aRegion.
    84      */
    85     static void ClipToRegion(mozilla::gfx::DrawTarget* aTarget, const nsIntRegion& aRegion);
    87     /**
    88      * Clip aContext to the region aRegion, snapping the rectangles.
    89      */
    90     static void ClipToRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion);
    92     /**
    93      * Clip aTarget to the region aRegion, snapping the rectangles.
    94      */
    95     static void ClipToRegionSnapped(mozilla::gfx::DrawTarget* aTarget, const nsIntRegion& aRegion);
    97     /**
    98      * Create a path consisting of rectangles in |aRegion|.
    99      */
   100     static void PathFromRegion(gfxContext* aContext, const nsIntRegion& aRegion);
   102     /**
   103      * Create a path consisting of rectangles in |aRegion|, snapping the rectangles.
   104      */
   105     static void PathFromRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion);
   107     /*
   108      * Convert image format to depth value
   109      */
   110     static int ImageFormatToDepth(gfxImageFormat aFormat);
   112     /**
   113      * Return the transform matrix that maps aFrom to the rectangle defined by
   114      * aToTopLeft/aToTopRight/aToBottomRight. aFrom must be
   115      * nonempty and the destination rectangle must be axis-aligned.
   116      */
   117     static gfxMatrix TransformRectToRect(const gfxRect& aFrom,
   118                                          const gfxPoint& aToTopLeft,
   119                                          const gfxPoint& aToTopRight,
   120                                          const gfxPoint& aToBottomRight);
   122     static Matrix TransformRectToRect(const gfxRect& aFrom,
   123                                       const IntPoint& aToTopLeft,
   124                                       const IntPoint& aToTopRight,
   125                                       const IntPoint& aToBottomRight);
   127     /**
   128      * If aIn can be represented exactly using an nsIntRect (i.e.
   129      * integer-aligned edges and coordinates in the int32_t range) then we
   130      * set aOut to that rectangle, otherwise return failure.
   131     */
   132     static bool GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut);
   134     /**
   135      * Return the smallest power of kScaleResolution (2) greater than or equal to
   136      * aVal.
   137      */
   138     static gfxFloat ClampToScaleFactor(gfxFloat aVal);
   140     /**
   141      * Helper function for ConvertYCbCrToRGB that finds the
   142      * RGB buffer size and format for given YCbCrImage.
   143      * @param aSuggestedFormat will be set to gfxImageFormat::RGB24
   144      *   if the desired format is not supported.
   145      * @param aSuggestedSize will be set to the picture size from aData
   146      *   if either the suggested size was {0,0}
   147      *   or simultaneous scaling and conversion is not supported.
   148      */
   149     static void
   150     GetYCbCrToRGBDestFormatAndSize(const mozilla::layers::PlanarYCbCrData& aData,
   151                                    gfxImageFormat& aSuggestedFormat,
   152                                    gfxIntSize& aSuggestedSize);
   154     /**
   155      * Convert YCbCrImage into RGB aDestBuffer
   156      * Format and Size parameters must have
   157      *   been passed to GetYCbCrToRGBDestFormatAndSize
   158      */
   159     static void
   160     ConvertYCbCrToRGB(const mozilla::layers::PlanarYCbCrData& aData,
   161                       const gfxImageFormat& aDestFormat,
   162                       const gfxIntSize& aDestSize,
   163                       unsigned char* aDestBuffer,
   164                       int32_t aStride);
   166     /**
   167      * Creates a copy of aSurface, but having the SurfaceFormat aFormat.
   168      *
   169      * This function always creates a new surface. Do not call it if aSurface's
   170      * format is the same as aFormat. Such a non-conversion would just be an
   171      * unnecessary and wasteful copy (this function asserts to prevent that).
   172      *
   173      * This function is intended to be called by code that needs to access the
   174      * pixel data of the surface, but doesn't want to have lots of branches
   175      * to handle different pixel data formats (code which would become out of
   176      * date if and when new formats are added). Callers can use this function
   177      * to copy the surface to a specified format so that they only have to
   178      * handle pixel data in that one format.
   179      *
   180      * WARNING: There are format conversions that will not be supported by this
   181      * function. It very much depends on what the Moz2D backends support. If
   182      * the temporary B8G8R8A8 DrawTarget that this function creates has a
   183      * backend that supports DrawSurface() calls passing a surface with
   184      * aSurface's format it will work. Otherwise it will not.
   185      *
   186      *                      *** IMPORTANT PERF NOTE ***
   187      *
   188      * This function exists partly because format conversion is fraught with
   189      * non-obvious performance hazards, so we don't want Moz2D consumers to be
   190      * doing their own format conversion. Do not try to do so, or at least read
   191      * the comments in this functions implemtation. That said, the copy that
   192      * this function carries out has a cost and, although this function tries
   193      * to avoid perf hazards such as expensive uploads to/readbacks from the
   194      * GPU, it can't guarantee that it always successfully does so. Perf
   195      * critical code that can directly handle the common formats that it
   196      * encounters in a way that is cheaper than a copy-with-format-conversion
   197      * should consider doing so, and only use this function as a fallback to
   198      * handle other formats.
   199      *
   200      * XXXjwatt it would be nice if SourceSurface::GetDataSurface took a
   201      * SurfaceFormat argument (with a default argument meaning "use the
   202      * existing surface's format") and returned a DataSourceSurface in that
   203      * format. (There would then be an issue of callers maybe failing to
   204      * realize format conversion may involve expensive copying/uploading/
   205      * readback.)
   206      */
   207     static mozilla::TemporaryRef<DataSourceSurface>
   208     CopySurfaceToDataSourceSurfaceWithFormat(SourceSurface* aSurface,
   209                                              SurfaceFormat aFormat);
   211     static const uint8_t sUnpremultiplyTable[256*256];
   212     static const uint8_t sPremultiplyTable[256*256];
   213 #ifdef MOZ_DUMP_PAINTING
   214     /**
   215      * Writes a binary PNG file.
   216      */
   217     static void WriteAsPNG(mozilla::gfx::DrawTarget* aDT, const char* aFile);
   219     /**
   220      * Write as a PNG encoded Data URL to stdout.
   221      */
   222     static void DumpAsDataURL(mozilla::gfx::DrawTarget* aDT);
   224     /**
   225      * Copy a PNG encoded Data URL to the clipboard.
   226      */
   227     static void CopyAsDataURL(mozilla::gfx::DrawTarget* aDT);
   229     static bool sDumpPaintList;
   230     static bool sDumpPainting;
   231     static bool sDumpPaintingToFile;
   232     static FILE* sDumpPaintFile;
   234     /**
   235      * Writes a binary PNG file.
   236      * Expensive. Creates a DataSourceSurface, then a DrawTarget, then passes to DrawTarget overloads
   237      */
   238     static void WriteAsPNG(mozilla::RefPtr<mozilla::gfx::SourceSurface> aSourceSurface, const char* aFile);
   240     /**
   241      * Write as a PNG encoded Data URL to stdout.
   242      * Expensive. Creates a DataSourceSurface, then a DrawTarget, then passes to DrawTarget overloads
   243      */
   244     static void DumpAsDataURL(mozilla::RefPtr<mozilla::gfx::SourceSurface> aSourceSurface);
   246     /**
   247      * Copy a PNG encoded Data URL to the clipboard.
   248      * Expensive. Creates a DataSourceSurface, then a DrawTarget, then passes to DrawTarget overloads
   249      */
   250     static void CopyAsDataURL(mozilla::RefPtr<mozilla::gfx::SourceSurface> aSourceSurface);
   251 #endif
   252 };
   254 namespace mozilla {
   255 namespace gfx {
   258 /* These techniques are suggested by "Bit Twiddling Hacks"
   259  */
   261 /**
   262  * Returns true if |aNumber| is a power of two
   263  * 0 is incorreclty considered a power of two
   264  */
   265 static inline bool
   266 IsPowerOfTwo(int aNumber)
   267 {
   268     return (aNumber & (aNumber - 1)) == 0;
   269 }
   271 /**
   272  * Returns the first integer greater than |aNumber| which is a power of two
   273  * Undefined for |aNumber| < 0
   274  */
   275 static inline int
   276 NextPowerOfTwo(int aNumber)
   277 {
   278 #if defined(__arm__)
   279     return 1 << (32 - __builtin_clz(aNumber - 1));
   280 #else
   281     --aNumber;
   282     aNumber |= aNumber >> 1;
   283     aNumber |= aNumber >> 2;
   284     aNumber |= aNumber >> 4;
   285     aNumber |= aNumber >> 8;
   286     aNumber |= aNumber >> 16;
   287     return ++aNumber;
   288 #endif
   289 }
   291 } // namespace gfx
   292 } // namespace mozilla
   294 #endif

mercurial