Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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