Coverage Report

Created: 2018-09-25 14:53

/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