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.

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

mercurial