/src/mozilla-central/gfx/thebes/gfxUtils.h
Line | Count | Source (jump to first uncovered line) |
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 GFX_UTILS_H |
7 | | #define GFX_UTILS_H |
8 | | |
9 | | #include "gfxTypes.h" |
10 | | #include "ImageTypes.h" |
11 | | #include "imgIContainer.h" |
12 | | #include "mozilla/gfx/2D.h" |
13 | | #include "mozilla/RefPtr.h" |
14 | | #include "mozilla/UniquePtr.h" |
15 | | #include "nsColor.h" |
16 | | #include "nsPrintfCString.h" |
17 | | #include "nsRegionFwd.h" |
18 | | #include "mozilla/gfx/Rect.h" |
19 | | #include "mozilla/CheckedInt.h" |
20 | | #include "mozilla/webrender/WebRenderTypes.h" |
21 | | |
22 | | class gfxASurface; |
23 | | class gfxDrawable; |
24 | | struct gfxQuad; |
25 | | class nsIInputStream; |
26 | | class nsIGfxInfo; |
27 | | class nsIPresShell; |
28 | | |
29 | | namespace mozilla { |
30 | | namespace layers { |
31 | | class WebRenderBridgeChild; |
32 | | class GlyphArray; |
33 | | struct PlanarYCbCrData; |
34 | | class WebRenderCommand; |
35 | | } // namespace layers |
36 | | namespace image { |
37 | | class ImageRegion; |
38 | | } // namespace image |
39 | | namespace wr { |
40 | | class DisplayListBuilder; |
41 | | } // namespace wr |
42 | | } // namespace mozilla |
43 | | |
44 | | class gfxUtils { |
45 | | public: |
46 | | typedef mozilla::gfx::DataSourceSurface DataSourceSurface; |
47 | | typedef mozilla::gfx::DrawTarget DrawTarget; |
48 | | typedef mozilla::gfx::IntPoint IntPoint; |
49 | | typedef mozilla::gfx::Matrix Matrix; |
50 | | typedef mozilla::gfx::SourceSurface SourceSurface; |
51 | | typedef mozilla::gfx::SurfaceFormat SurfaceFormat; |
52 | | typedef mozilla::image::ImageRegion ImageRegion; |
53 | | |
54 | | /* |
55 | | * Premultiply or Unpremultiply aSourceSurface, writing the result |
56 | | * to aDestSurface or back into aSourceSurface if aDestSurface is null. |
57 | | * |
58 | | * If aDestSurface is given, it must have identical format, dimensions, and |
59 | | * stride as the source. |
60 | | * |
61 | | * If the source is not SurfaceFormat::A8R8G8B8_UINT32, no operation is performed. If |
62 | | * aDestSurface is given, the data is copied over. |
63 | | */ |
64 | | static bool PremultiplyDataSurface(DataSourceSurface* srcSurf, |
65 | | DataSourceSurface* destSurf); |
66 | | static bool UnpremultiplyDataSurface(DataSourceSurface* srcSurf, |
67 | | DataSourceSurface* destSurf); |
68 | | |
69 | | static already_AddRefed<DataSourceSurface> |
70 | | CreatePremultipliedDataSurface(DataSourceSurface* srcSurf); |
71 | | static already_AddRefed<DataSourceSurface> |
72 | | CreateUnpremultipliedDataSurface(DataSourceSurface* srcSurf); |
73 | | |
74 | | static void ConvertBGRAtoRGBA(uint8_t* aData, uint32_t aLength); |
75 | | |
76 | | /** |
77 | | * Draw something drawable while working around limitations like bad support |
78 | | * for EXTEND_PAD, lack of source-clipping, or cairo / pixman bugs with |
79 | | * extreme user-space-to-image-space transforms. |
80 | | * |
81 | | * The input parameters here usually come from the output of our image |
82 | | * snapping algorithm in nsLayoutUtils.cpp. |
83 | | * This method is split from nsLayoutUtils::DrawPixelSnapped to allow for |
84 | | * adjusting the parameters. For example, certain images with transparent |
85 | | * margins only have a drawable subimage. For those images, imgFrame::Draw |
86 | | * will tweak the rects and transforms that it gets from the pixel snapping |
87 | | * algorithm before passing them on to this method. |
88 | | */ |
89 | | static void DrawPixelSnapped(gfxContext* aContext, |
90 | | gfxDrawable* aDrawable, |
91 | | const gfxSize& aImageSize, |
92 | | const ImageRegion& aRegion, |
93 | | const mozilla::gfx::SurfaceFormat aFormat, |
94 | | mozilla::gfx::SamplingFilter aSamplingFilter, |
95 | | uint32_t aImageFlags = imgIContainer::FLAG_NONE, |
96 | | gfxFloat aOpacity = 1.0, |
97 | | bool aUseOptimalFillOp = true); |
98 | | |
99 | | /** |
100 | | * Clip aContext to the region aRegion. |
101 | | */ |
102 | | static void ClipToRegion(gfxContext* aContext, const nsIntRegion& aRegion); |
103 | | |
104 | | /** |
105 | | * Clip aTarget to the region aRegion. |
106 | | */ |
107 | | static void ClipToRegion(mozilla::gfx::DrawTarget* aTarget, const nsIntRegion& aRegion); |
108 | | |
109 | | /* |
110 | | * Convert image format to depth value |
111 | | */ |
112 | | static int ImageFormatToDepth(gfxImageFormat aFormat); |
113 | | |
114 | | /** |
115 | | * Return the transform matrix that maps aFrom to the rectangle defined by |
116 | | * aToTopLeft/aToTopRight/aToBottomRight. aFrom must be |
117 | | * nonempty and the destination rectangle must be axis-aligned. |
118 | | */ |
119 | | static gfxMatrix TransformRectToRect(const gfxRect& aFrom, |
120 | | const gfxPoint& aToTopLeft, |
121 | | const gfxPoint& aToTopRight, |
122 | | const gfxPoint& aToBottomRight); |
123 | | |
124 | | static Matrix TransformRectToRect(const gfxRect& aFrom, |
125 | | const IntPoint& aToTopLeft, |
126 | | const IntPoint& aToTopRight, |
127 | | const IntPoint& aToBottomRight); |
128 | | |
129 | | /** |
130 | | * If aIn can be represented exactly using an gfx::IntRect (i.e. |
131 | | * integer-aligned edges and coordinates in the int32_t range) then we |
132 | | * set aOut to that rectangle, otherwise return failure. |
133 | | */ |
134 | | static bool GfxRectToIntRect(const gfxRect& aIn, mozilla::gfx::IntRect* aOut); |
135 | | |
136 | | /* Conditions this border to Cairo's max coordinate space. |
137 | | * The caller can check IsEmpty() after Condition() -- if it's TRUE, |
138 | | * the caller can possibly avoid doing any extra rendering. |
139 | | */ |
140 | | static void ConditionRect(gfxRect& aRect); |
141 | | |
142 | | /* |
143 | | * Transform this rectangle with aMatrix, resulting in a gfxQuad. |
144 | | */ |
145 | | static gfxQuad TransformToQuad(const gfxRect& aRect, |
146 | | const mozilla::gfx::Matrix4x4& aMatrix); |
147 | | |
148 | | /** |
149 | | * Return the smallest power of kScaleResolution (2) greater than or equal to |
150 | | * aVal. If aRoundDown is specified, the power of 2 will rather be less than |
151 | | * or equal to aVal. |
152 | | */ |
153 | | static float ClampToScaleFactor(float aVal, bool aRoundDown = false); |
154 | | |
155 | | /** |
156 | | * Clears surface to aColor (which defaults to transparent black). |
157 | | */ |
158 | | static void ClearThebesSurface(gfxASurface* aSurface); |
159 | | |
160 | | static const float* YuvToRgbMatrix4x3RowMajor(mozilla::YUVColorSpace aYUVColorSpace); |
161 | | static const float* YuvToRgbMatrix3x3ColumnMajor(mozilla::YUVColorSpace aYUVColorSpace); |
162 | | static const float* YuvToRgbMatrix4x4ColumnMajor(mozilla::YUVColorSpace aYUVColorSpace); |
163 | | |
164 | | /** |
165 | | * Creates a copy of aSurface, but having the SurfaceFormat aFormat. |
166 | | * |
167 | | * This function always creates a new surface. Do not call it if aSurface's |
168 | | * format is the same as aFormat. Such a non-conversion would just be an |
169 | | * unnecessary and wasteful copy (this function asserts to prevent that). |
170 | | * |
171 | | * This function is intended to be called by code that needs to access the |
172 | | * pixel data of the surface, but doesn't want to have lots of branches |
173 | | * to handle different pixel data formats (code which would become out of |
174 | | * date if and when new formats are added). Callers can use this function |
175 | | * to copy the surface to a specified format so that they only have to |
176 | | * handle pixel data in that one format. |
177 | | * |
178 | | * WARNING: There are format conversions that will not be supported by this |
179 | | * function. It very much depends on what the Moz2D backends support. If |
180 | | * the temporary B8G8R8A8 DrawTarget that this function creates has a |
181 | | * backend that supports DrawSurface() calls passing a surface with |
182 | | * aSurface's format it will work. Otherwise it will not. |
183 | | * |
184 | | * *** IMPORTANT PERF NOTE *** |
185 | | * |
186 | | * This function exists partly because format conversion is fraught with |
187 | | * non-obvious performance hazards, so we don't want Moz2D consumers to be |
188 | | * doing their own format conversion. Do not try to do so, or at least read |
189 | | * the comments in this functions implemtation. That said, the copy that |
190 | | * this function carries out has a cost and, although this function tries |
191 | | * to avoid perf hazards such as expensive uploads to/readbacks from the |
192 | | * GPU, it can't guarantee that it always successfully does so. Perf |
193 | | * critical code that can directly handle the common formats that it |
194 | | * encounters in a way that is cheaper than a copy-with-format-conversion |
195 | | * should consider doing so, and only use this function as a fallback to |
196 | | * handle other formats. |
197 | | * |
198 | | * XXXjwatt it would be nice if SourceSurface::GetDataSurface took a |
199 | | * SurfaceFormat argument (with a default argument meaning "use the |
200 | | * existing surface's format") and returned a DataSourceSurface in that |
201 | | * format. (There would then be an issue of callers maybe failing to |
202 | | * realize format conversion may involve expensive copying/uploading/ |
203 | | * readback.) |
204 | | */ |
205 | | static already_AddRefed<DataSourceSurface> |
206 | | CopySurfaceToDataSourceSurfaceWithFormat(SourceSurface* aSurface, |
207 | | SurfaceFormat aFormat); |
208 | | |
209 | | /** |
210 | | * Return a color that can be used to identify a frame with a given frame number. |
211 | | * The colors will cycle after sNumFrameColors. You can query colors 0 .. sNumFrameColors-1 |
212 | | * to get all the colors back. |
213 | | */ |
214 | | static const mozilla::gfx::Color& GetColorForFrameNumber(uint64_t aFrameNumber); |
215 | | static const uint32_t sNumFrameColors; |
216 | | |
217 | | |
218 | | enum BinaryOrData { |
219 | | eBinaryEncode, |
220 | | eDataURIEncode |
221 | | }; |
222 | | |
223 | | /** |
224 | | * Encodes the given surface to PNG/JPEG/BMP/etc. using imgIEncoder. |
225 | | * If both aFile and aString are null, the encoded data is copied to the |
226 | | * clipboard. |
227 | | * |
228 | | * @param aMimeType The MIME-type of the image type that the surface is to |
229 | | * be encoded to. Used to create an appropriate imgIEncoder instance to |
230 | | * do the encoding. |
231 | | * |
232 | | * @param aOutputOptions Passed directly to imgIEncoder::InitFromData as |
233 | | * the value of the |outputOptions| parameter. Callers are responsible |
234 | | * for making sure that this is a sane value for the passed MIME-type |
235 | | * (i.e. for the type of encoder that will be created). |
236 | | * |
237 | | * @aBinaryOrData Flag used to determine if the surface is simply encoded |
238 | | * to the requested binary image format, or if the binary image is |
239 | | * further converted to base-64 and written out as a 'data:' URI. |
240 | | * |
241 | | * @aFile If specified, the encoded data is written out to aFile. |
242 | | * |
243 | | * @aString If specified, the encoded data is written out to aString. |
244 | | * |
245 | | * TODO: Copying to the clipboard as a binary file is not currently |
246 | | * supported. |
247 | | */ |
248 | | static nsresult |
249 | | EncodeSourceSurface(SourceSurface* aSurface, |
250 | | const nsACString& aMimeType, |
251 | | const nsAString& aOutputOptions, |
252 | | BinaryOrData aBinaryOrData, |
253 | | FILE* aFile, |
254 | | nsACString* aString = nullptr); |
255 | | |
256 | | /** |
257 | | * Write as a PNG file to the path aFile. |
258 | | */ |
259 | | static void WriteAsPNG(SourceSurface* aSurface, const nsAString& aFile); |
260 | | static void WriteAsPNG(SourceSurface* aSurface, const char* aFile); |
261 | | static void WriteAsPNG(DrawTarget* aDT, const nsAString& aFile); |
262 | | static void WriteAsPNG(DrawTarget* aDT, const char* aFile); |
263 | | static void WriteAsPNG(nsIPresShell* aShell, const char* aFile); |
264 | | |
265 | | /** |
266 | | * Dump as a PNG encoded Data URL to a FILE stream (using stdout by |
267 | | * default). |
268 | | * |
269 | | * Rather than giving aFile a default argument we have separate functions |
270 | | * to make them easier to use from a debugger. |
271 | | */ |
272 | | static void DumpAsDataURI(SourceSurface* aSourceSurface, FILE* aFile); |
273 | | static inline void DumpAsDataURI(SourceSurface* aSourceSurface) { |
274 | | DumpAsDataURI(aSourceSurface, stdout); |
275 | | } |
276 | | static void DumpAsDataURI(DrawTarget* aDT, FILE* aFile); |
277 | | static inline void DumpAsDataURI(DrawTarget* aDT) { |
278 | | DumpAsDataURI(aDT, stdout); |
279 | | } |
280 | | static nsCString GetAsDataURI(SourceSurface* aSourceSurface); |
281 | | static nsCString GetAsDataURI(DrawTarget* aDT); |
282 | | static nsCString GetAsLZ4Base64Str(DataSourceSurface* aSourceSurface); |
283 | | |
284 | | static mozilla::UniquePtr<uint8_t[]> GetImageBuffer(DataSourceSurface* aSurface, |
285 | | bool aIsAlphaPremultiplied, |
286 | | int32_t* outFormat); |
287 | | |
288 | | static nsresult GetInputStream(DataSourceSurface* aSurface, |
289 | | bool aIsAlphaPremultiplied, |
290 | | const char* aMimeType, |
291 | | const char16_t* aEncoderOptions, |
292 | | nsIInputStream** outStream); |
293 | | |
294 | | static nsresult ThreadSafeGetFeatureStatus(const nsCOMPtr<nsIGfxInfo>& gfxInfo, |
295 | | int32_t feature, |
296 | | nsACString& failureId, |
297 | | int32_t* status); |
298 | | |
299 | | static void RemoveShaderCacheFromDiskIfNecessary(); |
300 | | |
301 | | /** |
302 | | * Copy to the clipboard as a PNG encoded Data URL. |
303 | | */ |
304 | | static void CopyAsDataURI(SourceSurface* aSourceSurface); |
305 | | static void CopyAsDataURI(DrawTarget* aDT); |
306 | | |
307 | | static bool DumpDisplayList(); |
308 | | |
309 | | static FILE* sDumpPaintFile; |
310 | | }; |
311 | | |
312 | | namespace mozilla { |
313 | | namespace gfx { |
314 | | |
315 | | /** |
316 | | * If the CMS mode is eCMSMode_All, these functions transform the passed |
317 | | * color to a device color using the transform returened by gfxPlatform:: |
318 | | * GetCMSRGBTransform(). If the CMS mode is some other value, the color is |
319 | | * returned unchanged (other than a type change to Moz2D Color, if |
320 | | * applicable). |
321 | | */ |
322 | | Color ToDeviceColor(Color aColor); |
323 | | Color ToDeviceColor(nscolor aColor); |
324 | | |
325 | | /** |
326 | | * Performs a checked multiply of the given width, height, and bytes-per-pixel |
327 | | * values. |
328 | | */ |
329 | | static inline CheckedInt<uint32_t> |
330 | | SafeBytesForBitmap(uint32_t aWidth, uint32_t aHeight, unsigned aBytesPerPixel) |
331 | 0 | { |
332 | 0 | MOZ_ASSERT(aBytesPerPixel > 0); |
333 | 0 | CheckedInt<uint32_t> width = uint32_t(aWidth); |
334 | 0 | CheckedInt<uint32_t> height = uint32_t(aHeight); |
335 | 0 | return width * height * aBytesPerPixel; |
336 | 0 | } Unexecuted instantiation: gfxPlatform.cpp:mozilla::gfx::SafeBytesForBitmap(unsigned int, unsigned int, unsigned int) Unexecuted instantiation: gfxPlatformGtk.cpp:mozilla::gfx::SafeBytesForBitmap(unsigned int, unsigned int, unsigned int) Unexecuted instantiation: VRDisplayHost.cpp:mozilla::gfx::SafeBytesForBitmap(unsigned int, unsigned int, unsigned int) Unexecuted instantiation: VRDisplayLocal.cpp:mozilla::gfx::SafeBytesForBitmap(unsigned int, unsigned int, unsigned int) Unexecuted instantiation: gfxVRExternal.cpp:mozilla::gfx::SafeBytesForBitmap(unsigned int, unsigned int, unsigned int) Unexecuted instantiation: gfxVROpenVR.cpp:mozilla::gfx::SafeBytesForBitmap(unsigned int, unsigned int, unsigned int) Unexecuted instantiation: gfxVRPuppet.cpp:mozilla::gfx::SafeBytesForBitmap(unsigned int, unsigned int, unsigned int) Unexecuted instantiation: Unified_cpp_gfx_vr0.cpp:mozilla::gfx::SafeBytesForBitmap(unsigned int, unsigned int, unsigned int) Unexecuted instantiation: Unified_cpp_gfx_vr1.cpp:mozilla::gfx::SafeBytesForBitmap(unsigned int, unsigned int, unsigned int) |
337 | | |
338 | | } // namespace gfx |
339 | | } // namespace mozilla |
340 | | |
341 | | #endif |