1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef _MOZILLA_GFX_2D_H
8 #define _MOZILLA_GFX_2D_H
9 
10 #include "Types.h"
11 #include "Point.h"
12 #include "Rect.h"
13 #include "Matrix.h"
14 #include "Quaternion.h"
15 #include "UserData.h"
16 #include "FontVariation.h"
17 #include <vector>
18 
19 // GenericRefCountedBase allows us to hold on to refcounted objects of any type
20 // (contrary to RefCounted<T> which requires knowing the type T) and, in
21 // particular, without having a dependency on that type. This is used for
22 // DrawTargetSkia to be able to hold on to a GLContext.
23 #include "mozilla/GenericRefCounted.h"
24 #include "mozilla/MemoryReporting.h"
25 #include "mozilla/Path.h"
26 
27 // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
28 // outparams using the &-operator. But it will have to do as there's no easy
29 // solution.
30 #include "mozilla/RefPtr.h"
31 #include "mozilla/StaticMutex.h"
32 #include "mozilla/StaticPtr.h"
33 #include "mozilla/ThreadSafeWeakPtr.h"
34 #include "mozilla/Atomics.h"
35 
36 #include "mozilla/DebugOnly.h"
37 
38 #include "nsRegionFwd.h"
39 
40 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
41 #  ifndef MOZ_ENABLE_FREETYPE
42 #    define MOZ_ENABLE_FREETYPE
43 #  endif
44 #endif
45 
46 struct _cairo_surface;
47 typedef _cairo_surface cairo_surface_t;
48 
49 struct _cairo_scaled_font;
50 typedef _cairo_scaled_font cairo_scaled_font_t;
51 
52 struct FT_LibraryRec_;
53 typedef FT_LibraryRec_* FT_Library;
54 
55 struct FT_FaceRec_;
56 typedef FT_FaceRec_* FT_Face;
57 
58 typedef int FT_Error;
59 
60 struct _FcPattern;
61 typedef _FcPattern FcPattern;
62 
63 struct ID3D11Texture2D;
64 struct ID3D11Device;
65 struct ID2D1Device;
66 struct ID2D1DeviceContext;
67 struct ID2D1Multithread;
68 struct IDWriteFactory;
69 struct IDWriteRenderingParams;
70 struct IDWriteFontFace;
71 struct IDWriteFontCollection;
72 
73 class SkCanvas;
74 struct gfxFontStyle;
75 
76 struct CGContext;
77 typedef struct CGContext* CGContextRef;
78 
79 struct CGFont;
80 typedef CGFont* CGFontRef;
81 
82 namespace mozilla {
83 
84 class Mutex;
85 
86 namespace layers {
87 class TextureData;
88 }
89 
90 namespace wr {
91 struct FontInstanceOptions;
92 struct FontInstancePlatformOptions;
93 }  // namespace wr
94 
95 namespace gfx {
96 class UnscaledFont;
97 class ScaledFont;
98 }  // namespace gfx
99 
100 namespace gfx {
101 
102 class AlphaBoxBlur;
103 class ScaledFont;
104 class SourceSurface;
105 class DataSourceSurface;
106 class DrawTarget;
107 class DrawEventRecorder;
108 class FilterNode;
109 class LogForwarder;
110 
111 struct NativeSurface {
112   NativeSurfaceType mType;
113   SurfaceFormat mFormat;
114   gfx::IntSize mSize;
115   void* mSurface;
116 };
117 
118 /**
119  * This structure is used to send draw options that are universal to all drawing
120  * operations.
121  */
122 struct DrawOptions {
123   /// For constructor parameter description, see member data documentation.
124   explicit DrawOptions(Float aAlpha = 1.0f,
125                        CompositionOp aCompositionOp = CompositionOp::OP_OVER,
126                        AntialiasMode aAntialiasMode = AntialiasMode::DEFAULT)
mAlphaDrawOptions127       : mAlpha(aAlpha),
128         mCompositionOp(aCompositionOp),
129         mAntialiasMode(aAntialiasMode) {}
130 
131   Float mAlpha; /**< Alpha value by which the mask generated by this
132                      operation is multiplied. */
133   CompositionOp mCompositionOp; /**< The operator that indicates how the source
134                                    and destination patterns are blended. */
135   AntialiasMode mAntialiasMode; /**< The AntiAlias mode used for this drawing
136                                      operation. */
137 };
138 
139 /**
140  * This structure is used to send stroke options that are used in stroking
141  * operations.
142  */
143 struct StrokeOptions {
144   /// For constructor parameter description, see member data documentation.
145   explicit StrokeOptions(Float aLineWidth = 1.0f,
146                          JoinStyle aLineJoin = JoinStyle::MITER_OR_BEVEL,
147                          CapStyle aLineCap = CapStyle::BUTT,
148                          Float aMiterLimit = 10.0f, size_t aDashLength = 0,
149                          const Float* aDashPattern = 0, Float aDashOffset = 0.f)
mLineWidthStrokeOptions150       : mLineWidth(aLineWidth),
151         mMiterLimit(aMiterLimit),
152         mDashPattern(aDashLength > 0 ? aDashPattern : 0),
153         mDashLength(aDashLength),
154         mDashOffset(aDashOffset),
155         mLineJoin(aLineJoin),
156         mLineCap(aLineCap) {
157     MOZ_ASSERT(aDashLength == 0 || aDashPattern);
158   }
159 
160   Float mLineWidth;          //!< Width of the stroke in userspace.
161   Float mMiterLimit;         //!< Miter limit in units of linewidth
162   const Float* mDashPattern; /**< Series of on/off userspace lengths defining
163                                 dash. Owned by the caller; must live at least as
164                                 long as this StrokeOptions.
165                                   mDashPattern != null <=> mDashLength > 0. */
166   size_t mDashLength;        //!< Number of on/off lengths in mDashPattern.
167   Float mDashOffset;         /**< Userspace offset within mDashPattern at which
168                                   stroking begins. */
169   JoinStyle mLineJoin;       //!< Join style used for joining lines.
170   CapStyle mLineCap;         //!< Cap style used for capping lines.
171 };
172 
173 /**
174  * This structure supplies additional options for calls to DrawSurface.
175  */
176 struct DrawSurfaceOptions {
177   /// For constructor parameter description, see member data documentation.
178   explicit DrawSurfaceOptions(
179       SamplingFilter aSamplingFilter = SamplingFilter::LINEAR,
180       SamplingBounds aSamplingBounds = SamplingBounds::UNBOUNDED)
mSamplingFilterDrawSurfaceOptions181       : mSamplingFilter(aSamplingFilter), mSamplingBounds(aSamplingBounds) {}
182 
183   SamplingFilter
184       mSamplingFilter; /**< SamplingFilter used when resampling source surface
185                             region to the destination region. */
186   SamplingBounds mSamplingBounds; /**< This indicates whether the implementation
187                                      is allowed to sample pixels outside the
188                                      source rectangle as specified in
189                                      DrawSurface on the surface. */
190 };
191 
192 /**
193  * This class is used to store gradient stops, it can only be used with a
194  * matching DrawTarget. Not adhering to this condition will make a draw call
195  * fail.
196  */
197 class GradientStops : public external::AtomicRefCounted<GradientStops> {
198  public:
199   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops)
200   virtual ~GradientStops() = default;
201 
202   virtual BackendType GetBackendType() const = 0;
IsValid()203   virtual bool IsValid() const { return true; }
204 
205  protected:
206   GradientStops() = default;
207 };
208 
209 /**
210  * This is the base class for 'patterns'. Patterns describe the pixels used as
211  * the source for a masked composition operation that is done by the different
212  * drawing commands. These objects are not backend specific, however for
213  * example the gradient stops on a gradient pattern can be backend specific.
214  */
215 class Pattern {
216  public:
217   virtual ~Pattern() = default;
218 
219   virtual PatternType GetType() const = 0;
220 
221  protected:
222   Pattern() = default;
223 };
224 
225 class ColorPattern : public Pattern {
226  public:
227   // Explicit because consumers should generally use ToDeviceColor when
228   // creating a ColorPattern.
ColorPattern(const DeviceColor & aColor)229   explicit ColorPattern(const DeviceColor& aColor) : mColor(aColor) {}
230 
GetType()231   PatternType GetType() const override { return PatternType::COLOR; }
232 
233   DeviceColor mColor;
234 };
235 
236 /**
237  * This class is used for Linear Gradient Patterns, the gradient stops are
238  * stored in a separate object and are backend dependent. This class itself
239  * may be used on the stack.
240  */
241 class LinearGradientPattern : public Pattern {
242  public:
243   /// For constructor parameter description, see member data documentation.
244   LinearGradientPattern(const Point& aBegin, const Point& aEnd,
245                         GradientStops* aStops, const Matrix& aMatrix = Matrix())
mBegin(aBegin)246       : mBegin(aBegin), mEnd(aEnd), mStops(aStops), mMatrix(aMatrix) {}
247 
GetType()248   PatternType GetType() const override { return PatternType::LINEAR_GRADIENT; }
249 
250   Point mBegin;  //!< Start of the linear gradient
251   Point mEnd;    /**< End of the linear gradient - NOTE: In the case
252                       of a zero length gradient it will act as the
253                       color of the last stop. */
254   RefPtr<GradientStops>
255       mStops;     /**< GradientStops object for this gradient, this
256                        should match the backend type of the draw
257                        target this pattern will be used with. */
258   Matrix mMatrix; /**< A matrix that transforms the pattern into
259                        user space */
260 };
261 
262 /**
263  * This class is used for Radial Gradient Patterns, the gradient stops are
264  * stored in a separate object and are backend dependent. This class itself
265  * may be used on the stack.
266  */
267 class RadialGradientPattern : public Pattern {
268  public:
269   /// For constructor parameter description, see member data documentation.
270   RadialGradientPattern(const Point& aCenter1, const Point& aCenter2,
271                         Float aRadius1, Float aRadius2, GradientStops* aStops,
272                         const Matrix& aMatrix = Matrix())
mCenter1(aCenter1)273       : mCenter1(aCenter1),
274         mCenter2(aCenter2),
275         mRadius1(aRadius1),
276         mRadius2(aRadius2),
277         mStops(aStops),
278         mMatrix(aMatrix) {}
279 
GetType()280   PatternType GetType() const override { return PatternType::RADIAL_GRADIENT; }
281 
282   Point mCenter1;  //!< Center of the inner (focal) circle.
283   Point mCenter2;  //!< Center of the outer circle.
284   Float mRadius1;  //!< Radius of the inner (focal) circle.
285   Float mRadius2;  //!< Radius of the outer circle.
286   RefPtr<GradientStops>
287       mStops;      /**< GradientStops object for this gradient, this
288                         should match the backend type of the draw target
289                         this pattern will be used with. */
290   Matrix mMatrix;  //!< A matrix that transforms the pattern into user space
291 };
292 
293 /**
294  * This class is used for Conic Gradient Patterns, the gradient stops are
295  * stored in a separate object and are backend dependent. This class itself
296  * may be used on the stack.
297  */
298 class ConicGradientPattern : public Pattern {
299  public:
300   /// For constructor parameter description, see member data documentation.
301   ConicGradientPattern(const Point& aCenter, Float aAngle, Float aStartOffset,
302                        Float aEndOffset, GradientStops* aStops,
303                        const Matrix& aMatrix = Matrix())
mCenter(aCenter)304       : mCenter(aCenter),
305         mAngle(aAngle),
306         mStartOffset(aStartOffset),
307         mEndOffset(aEndOffset),
308         mStops(aStops),
309         mMatrix(aMatrix) {}
310 
GetType()311   PatternType GetType() const override { return PatternType::CONIC_GRADIENT; }
312 
313   Point mCenter;       //!< Center of the gradient
314   Float mAngle;        //!< Start angle of gradient
315   Float mStartOffset;  // Offset of first stop
316   Float mEndOffset;    // Offset of last stop
317   RefPtr<GradientStops>
318       mStops;      /**< GradientStops object for this gradient, this
319                         should match the backend type of the draw target
320                         this pattern will be used with. */
321   Matrix mMatrix;  //!< A matrix that transforms the pattern into user space
322 };
323 
324 /**
325  * This class is used for Surface Patterns, they wrap a surface and a
326  * repetition mode for the surface. This may be used on the stack.
327  */
328 class SurfacePattern : public Pattern {
329  public:
330   /// For constructor parameter description, see member data documentation.
331   SurfacePattern(SourceSurface* aSourceSurface, ExtendMode aExtendMode,
332                  const Matrix& aMatrix = Matrix(),
333                  SamplingFilter aSamplingFilter = SamplingFilter::GOOD,
334                  const IntRect& aSamplingRect = IntRect())
mSurface(aSourceSurface)335       : mSurface(aSourceSurface),
336         mExtendMode(aExtendMode),
337         mSamplingFilter(aSamplingFilter),
338         mMatrix(aMatrix),
339         mSamplingRect(aSamplingRect) {}
340 
GetType()341   PatternType GetType() const override { return PatternType::SURFACE; }
342 
343   RefPtr<SourceSurface> mSurface;  //!< Surface to use for drawing
344   ExtendMode mExtendMode; /**< This determines how the image is extended
345                                outside the bounds of the image */
346   SamplingFilter
347       mSamplingFilter;  //!< Resampling filter for resampling the image.
348   Matrix mMatrix;       //!< Transforms the pattern into user space
349 
350   IntRect mSamplingRect; /**< Rect that must not be sampled outside of,
351                               or an empty rect if none has been
352                               specified. */
353 };
354 
355 class StoredPattern;
356 class DrawTargetCaptureImpl;
357 
358 static const int32_t kReasonableSurfaceSize = 8192;
359 
360 /**
361  * This is the base class for source surfaces. These objects are surfaces
362  * which may be used as a source in a SurfacePattern or a DrawSurface call.
363  * They cannot be drawn to directly.
364  *
365  * Although SourceSurface has thread-safe refcount, some SourceSurface cannot
366  * be used on random threads at the same time. Only DataSourceSurface can be
367  * used on random threads now. This will be fixed in the future. Eventually
368  * all SourceSurface should be thread-safe.
369  */
370 class SourceSurface : public external::AtomicRefCounted<SourceSurface> {
371  public:
372   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface)
373   virtual ~SourceSurface() = default;
374 
375   virtual SurfaceType GetType() const = 0;
376   virtual IntSize GetSize() const = 0;
377   /* GetRect is useful for when the underlying surface doesn't actually
378    * have a backing store starting at 0, 0. e.g. SourceSurfaceOffset */
GetRect()379   virtual IntRect GetRect() const { return IntRect(IntPoint(0, 0), GetSize()); }
380   virtual SurfaceFormat GetFormat() const = 0;
381 
382   /**
383    * Structure containing memory size information for the surface.
384    */
385   struct SizeOfInfo {
SizeOfInfoSizeOfInfo386     SizeOfInfo()
387         : mHeapBytes(0),
388           mNonHeapBytes(0),
389           mUnknownBytes(0),
390           mExternalHandles(0),
391           mExternalId(0),
392           mTypes(0) {}
393 
AccumulateSizeOfInfo394     void Accumulate(const SizeOfInfo& aOther) {
395       mHeapBytes += aOther.mHeapBytes;
396       mNonHeapBytes += aOther.mNonHeapBytes;
397       mUnknownBytes += aOther.mUnknownBytes;
398       mExternalHandles += aOther.mExternalHandles;
399       if (aOther.mExternalId) {
400         mExternalId = aOther.mExternalId;
401       }
402       mTypes |= aOther.mTypes;
403     }
404 
AddTypeSizeOfInfo405     void AddType(SurfaceType aType) { mTypes |= 1 << uint32_t(aType); }
406 
407     size_t mHeapBytes;        // Bytes allocated on the heap.
408     size_t mNonHeapBytes;     // Bytes allocated off the heap.
409     size_t mUnknownBytes;     // Bytes allocated to either, but unknown.
410     size_t mExternalHandles;  // Open handles for the surface.
411     uint64_t mExternalId;     // External ID for WebRender, if available.
412     uint32_t mTypes;          // Bit shifted values representing SurfaceType.
413   };
414 
415   /**
416    * Get the size information of the underlying data buffer.
417    */
SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,SizeOfInfo & aInfo)418   virtual void SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
419                                    SizeOfInfo& aInfo) const {
420     // Default is to estimate the footprint based on its size/format.
421     auto size = GetSize();
422     auto format = GetFormat();
423     aInfo.AddType(GetType());
424     aInfo.mUnknownBytes = size.width * size.height * BytesPerPixel(format);
425   }
426 
427   /** This returns false if some event has made this source surface invalid for
428    * usage with current DrawTargets. For example in the case of Direct2D this
429    * could return false if we have switched devices since this surface was
430    * created.
431    */
IsValid()432   virtual bool IsValid() const { return true; }
433 
434   /**
435    * This returns true if it is the same underlying surface data, even if
436    * the objects are different (e.g. indirection due to
437    * DataSourceSurfaceWrapper).
438    */
439   virtual bool Equals(SourceSurface* aOther, bool aSymmetric = true) {
440     return this == aOther ||
441            (aSymmetric && aOther && aOther->Equals(this, false));
442   }
443 
444   /**
445    * This function will return true if the surface type matches that of a
446    * DataSourceSurface and if GetDataSurface will return the same object.
447    */
IsDataSourceSurface()448   bool IsDataSourceSurface() const {
449     switch (GetType()) {
450       case SurfaceType::DATA:
451       case SurfaceType::DATA_SHARED:
452       case SurfaceType::DATA_RECYCLING_SHARED:
453       case SurfaceType::DATA_ALIGNED:
454         return true;
455       default:
456         return false;
457     }
458   }
459 
460   /**
461    * This function will get a DataSourceSurface for this surface, a
462    * DataSourceSurface's data can be accessed directly.
463    */
464   virtual already_AddRefed<DataSourceSurface> GetDataSurface() = 0;
465 
466   /** This function will return a SourceSurface without any offset. */
GetUnderlyingSurface()467   virtual already_AddRefed<SourceSurface> GetUnderlyingSurface() {
468     RefPtr<SourceSurface> surface = this;
469     return surface.forget();
470   }
471 
472   /** Tries to get this SourceSurface's native surface.  This will fail if aType
473    * is not the type of this SourceSurface's native surface.
474    */
GetNativeSurface(NativeSurfaceType aType)475   virtual void* GetNativeSurface(NativeSurfaceType aType) { return nullptr; }
476 
AddUserData(UserDataKey * key,void * userData,void (* destroy)(void *))477   void AddUserData(UserDataKey* key, void* userData, void (*destroy)(void*)) {
478     mUserData.Add(key, userData, destroy);
479   }
GetUserData(UserDataKey * key)480   void* GetUserData(UserDataKey* key) const { return mUserData.Get(key); }
RemoveUserData(UserDataKey * key)481   void RemoveUserData(UserDataKey* key) { mUserData.RemoveAndDestroy(key); }
482 
483  protected:
484   friend class DrawTargetCaptureImpl;
485   friend class StoredPattern;
486 
487   // This is for internal use, it ensures the SourceSurface's data remains
488   // valid during the lifetime of the SourceSurface.
489   // @todo XXX - We need something better here :(. But we may be able to get rid
490   // of CreateWrappingDataSourceSurface in the future.
GuaranteePersistance()491   virtual void GuaranteePersistance() {}
492 
493   UserData mUserData;
494 };
495 
496 class DataSourceSurface : public SourceSurface {
497  public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurface,override)498   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurface, override)
499   DataSourceSurface() : mMapCount(0) {}
500 
501 #ifdef DEBUG
~DataSourceSurface()502   virtual ~DataSourceSurface() { MOZ_ASSERT(mMapCount == 0); }
503 #endif
504 
505   struct MappedSurface {
506     uint8_t* mData;
507     int32_t mStride;
508   };
509 
510   enum MapType { READ, WRITE, READ_WRITE };
511 
512   /**
513    * This is a scoped version of Map(). Map() is called in the constructor and
514    * Unmap() in the destructor. Use this for automatic unmapping of your data
515    * surfaces.
516    *
517    * Use IsMapped() to verify whether Map() succeeded or not.
518    */
519   class ScopedMap final {
520    public:
ScopedMap(DataSourceSurface * aSurface,MapType aType)521     ScopedMap(DataSourceSurface* aSurface, MapType aType)
522         : mSurface(aSurface), mIsMapped(aSurface->Map(aType, &mMap)) {}
523 
ScopedMap(ScopedMap && aOther)524     ScopedMap(ScopedMap&& aOther)
525         : mSurface(std::move(aOther.mSurface)),
526           mMap(aOther.mMap),
527           mIsMapped(aOther.mIsMapped) {
528       aOther.mMap.mData = nullptr;
529       aOther.mIsMapped = false;
530     }
531 
532     ScopedMap& operator=(ScopedMap&& aOther) {
533       if (mIsMapped) {
534         mSurface->Unmap();
535       }
536       mSurface = std::move(aOther.mSurface);
537       mMap = aOther.mMap;
538       mIsMapped = aOther.mIsMapped;
539       aOther.mMap.mData = nullptr;
540       aOther.mIsMapped = false;
541       return *this;
542     }
543 
~ScopedMap()544     ~ScopedMap() {
545       if (mIsMapped) {
546         mSurface->Unmap();
547       }
548     }
549 
GetData()550     uint8_t* GetData() const {
551       MOZ_ASSERT(mIsMapped);
552       return mMap.mData;
553     }
554 
GetStride()555     int32_t GetStride() const {
556       MOZ_ASSERT(mIsMapped);
557       return mMap.mStride;
558     }
559 
GetMappedSurface()560     const MappedSurface* GetMappedSurface() const {
561       MOZ_ASSERT(mIsMapped);
562       return &mMap;
563     }
564 
GetSurface()565     const DataSourceSurface* GetSurface() const {
566       MOZ_ASSERT(mIsMapped);
567       return mSurface;
568     }
569 
IsMapped()570     bool IsMapped() const { return mIsMapped; }
571 
572    private:
573     ScopedMap(const ScopedMap& aOther) = delete;
574     ScopedMap& operator=(const ScopedMap& aOther) = delete;
575 
576     RefPtr<DataSourceSurface> mSurface;
577     MappedSurface mMap;
578     bool mIsMapped;
579   };
580 
GetType()581   SurfaceType GetType() const override { return SurfaceType::DATA; }
582   /** @deprecated
583    * Get the raw bitmap data of the surface.
584    * Can return null if there was OOM allocating surface data.
585    *
586    * Deprecated means you shouldn't be using this!! Use Map instead.
587    * Please deny any reviews which add calls to this!
588    */
589   virtual uint8_t* GetData() = 0;
590 
591   /** @deprecated
592    * Stride of the surface, distance in bytes between the start of the image
593    * data belonging to row y and row y+1. This may be negative.
594    * Can return 0 if there was OOM allocating surface data.
595    */
596   virtual int32_t Stride() = 0;
597 
598   /**
599    * The caller is responsible for ensuring aMappedSurface is not null.
600   // Althought Map (and Moz2D in general) isn't normally threadsafe,
601   // we want to allow it for SourceSurfaceRawData since it should
602   // always be fine (for reading at least).
603   //
604   // This is the same as the base class implementation except using
605   // mMapCount instead of mIsMapped since that breaks for multithread.
606   //
607   // Once mfbt supports Monitors we should implement proper read/write
608   // locking to prevent write races.
609    */
Map(MapType,MappedSurface * aMappedSurface)610   virtual bool Map(MapType, MappedSurface* aMappedSurface) {
611     aMappedSurface->mData = GetData();
612     aMappedSurface->mStride = Stride();
613     bool success = !!aMappedSurface->mData;
614     if (success) {
615       mMapCount++;
616     }
617     return success;
618   }
619 
Unmap()620   virtual void Unmap() {
621     mMapCount--;
622     MOZ_ASSERT(mMapCount >= 0);
623   }
624 
625   /**
626    * Returns a DataSourceSurface with the same data as this one, but
627    * guaranteed to have surface->GetType() == SurfaceType::DATA.
628    *
629    * The returning surface might be null, because of OOM or gfx device reset.
630    * The caller needs to do null-check before using it.
631    */
632   already_AddRefed<DataSourceSurface> GetDataSurface() override;
633 
634   /**
635    * Returns whether or not the data was allocated on the heap. This should
636    * be used to determine if the memory needs to be cleared to 0.
637    */
OnHeap()638   virtual bool OnHeap() const { return true; }
639 
640   /**
641    * Yields a dirty rect of what has changed since it was last called.
642    */
TakeDirtyRect()643   virtual Maybe<IntRect> TakeDirtyRect() { return Nothing(); }
644 
645   /**
646    * Indicate a region which has changed in the surface.
647    */
Invalidate(const IntRect & aDirtyRect)648   virtual void Invalidate(const IntRect& aDirtyRect) {}
649 
650  protected:
651   Atomic<int32_t> mMapCount;
652 };
653 
654 /** This is an abstract object that accepts path segments. */
655 class PathSink : public RefCounted<PathSink> {
656  public:
657   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathSink)
658   virtual ~PathSink() = default;
659 
660   /** Move the current point in the path, any figure currently being drawn will
661    * be considered closed during fill operations, however when stroking the
662    * closing line segment will not be drawn.
663    */
664   virtual void MoveTo(const Point& aPoint) = 0;
665   /** Add a linesegment to the current figure */
666   virtual void LineTo(const Point& aPoint) = 0;
667   /** Add a cubic bezier curve to the current figure */
668   virtual void BezierTo(const Point& aCP1, const Point& aCP2,
669                         const Point& aCP3) = 0;
670   /** Add a quadratic bezier curve to the current figure */
671   virtual void QuadraticBezierTo(const Point& aCP1, const Point& aCP2) = 0;
672   /** Close the current figure, this will essentially generate a line segment
673    * from the current point to the starting point for the current figure
674    */
675   virtual void Close() = 0;
676   /** Add an arc to the current figure */
677   virtual void Arc(const Point& aOrigin, float aRadius, float aStartAngle,
678                    float aEndAngle, bool aAntiClockwise = false) = 0;
679 
CurrentPoint()680   virtual Point CurrentPoint() const { return mCurrentPoint; }
681 
BeginPoint()682   virtual Point BeginPoint() const { return mBeginPoint; }
683 
SetCurrentPoint(const Point & aPoint)684   virtual void SetCurrentPoint(const Point& aPoint) { mCurrentPoint = aPoint; }
685 
SetBeginPoint(const Point & aPoint)686   virtual void SetBeginPoint(const Point& aPoint) { mBeginPoint = aPoint; }
687 
688  protected:
689   /** Point the current subpath is at - or where the next subpath will start
690    * if there is no active subpath.
691    */
692   Point mCurrentPoint;
693 
694   /** Position of the previous MoveTo operation. */
695   Point mBeginPoint;
696 };
697 
698 class PathBuilder;
699 class FlattenedPath;
700 
701 /** The path class is used to create (sets of) figures of any shape that can be
702  * filled or stroked to a DrawTarget
703  */
704 class Path : public external::AtomicRefCounted<Path> {
705  public:
706   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(Path)
707   virtual ~Path();
708 
709   virtual BackendType GetBackendType() const = 0;
710 
711   /** This returns a PathBuilder object that contains a copy of the contents of
712    * this path and is still writable.
713    */
CopyToBuilder()714   inline already_AddRefed<PathBuilder> CopyToBuilder() const {
715     return CopyToBuilder(GetFillRule());
716   }
TransformedCopyToBuilder(const Matrix & aTransform)717   inline already_AddRefed<PathBuilder> TransformedCopyToBuilder(
718       const Matrix& aTransform) const {
719     return TransformedCopyToBuilder(aTransform, GetFillRule());
720   }
721   /** This returns a PathBuilder object that contains a copy of the contents of
722    * this path, converted to use the specified FillRule, and still writable.
723    */
724   virtual already_AddRefed<PathBuilder> CopyToBuilder(
725       FillRule aFillRule) const = 0;
726   virtual already_AddRefed<PathBuilder> TransformedCopyToBuilder(
727       const Matrix& aTransform, FillRule aFillRule) const = 0;
728 
729   /** This function checks if a point lies within a path. It allows passing a
730    * transform that will transform the path to the coordinate space in which
731    * aPoint is given.
732    */
733   virtual bool ContainsPoint(const Point& aPoint,
734                              const Matrix& aTransform) const = 0;
735 
736   /** This function checks if a point lies within the stroke of a path using the
737    * specified strokeoptions. It allows passing a transform that will transform
738    * the path to the coordinate space in which aPoint is given.
739    */
740   virtual bool StrokeContainsPoint(const StrokeOptions& aStrokeOptions,
741                                    const Point& aPoint,
742                                    const Matrix& aTransform) const = 0;
743 
744   /** This functions gets the bounds of this path. These bounds are not
745    * guaranteed to be tight. A transform may be specified that gives the bounds
746    * after application of the transform.
747    */
748   virtual Rect GetBounds(const Matrix& aTransform = Matrix()) const = 0;
749 
750   /** This function gets the bounds of the stroke of this path using the
751    * specified strokeoptions. These bounds are not guaranteed to be tight.
752    * A transform may be specified that gives the bounds after application of
753    * the transform.
754    */
755   virtual Rect GetStrokedBounds(const StrokeOptions& aStrokeOptions,
756                                 const Matrix& aTransform = Matrix()) const = 0;
757 
758   /** Take the contents of this path and stream it to another sink, this works
759    * regardless of the backend that might be used for the destination sink.
760    */
761   virtual void StreamToSink(PathSink* aSink) const = 0;
762 
763   /** This gets the fillrule this path's builder was created with. This is not
764    * mutable.
765    */
766   virtual FillRule GetFillRule() const = 0;
767 
768   virtual Float ComputeLength();
769 
770   virtual Point ComputePointAtLength(Float aLength, Point* aTangent = nullptr);
771 
772  protected:
773   Path();
774   void EnsureFlattenedPath();
775 
776   RefPtr<FlattenedPath> mFlattenedPath;
777 };
778 
779 /** The PathBuilder class allows path creation. Once finish is called on the
780  * pathbuilder it may no longer be written to.
781  */
782 class PathBuilder : public PathSink {
783  public:
784   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilder, override)
785   /** Finish writing to the path and return a Path object that can be used for
786    * drawing. Future use of the builder results in a crash!
787    */
788   virtual already_AddRefed<Path> Finish() = 0;
789 
790   virtual BackendType GetBackendType() const = 0;
791 };
792 
793 struct Glyph {
794   uint32_t mIndex;
795   Point mPosition;
796 };
797 
798 static inline bool operator==(const Glyph& aOne, const Glyph& aOther) {
799   return aOne.mIndex == aOther.mIndex && aOne.mPosition == aOther.mPosition;
800 }
801 
802 /** This class functions as a glyph buffer that can be drawn to a DrawTarget.
803  * @todo XXX - This should probably contain the guts of gfxTextRun in the future
804  * as roc suggested. But for now it's a simple container for a glyph vector.
805  */
806 struct GlyphBuffer {
807   const Glyph*
808       mGlyphs;  //!< A pointer to a buffer of glyphs. Managed by the caller.
809   uint32_t mNumGlyphs;  //!< Number of glyphs mGlyphs points to.
810 };
811 
812 #ifdef MOZ_ENABLE_FREETYPE
813 class SharedFTFace;
814 
815 /** SharedFTFaceData abstracts data that may be used to back a SharedFTFace.
816  * Its main function is to manage the lifetime of the data and ensure that it
817  * lasts as long as the face.
818  */
819 class SharedFTFaceData {
820  public:
821   /** Utility for creating a new face from this data. */
822   virtual already_AddRefed<SharedFTFace> CloneFace(int aFaceIndex = 0) {
823     return nullptr;
824   }
825   /** Binds the data's lifetime to the face. */
826   virtual void BindData() = 0;
827   /** Signals that the data is no longer needed by a face. */
828   virtual void ReleaseData() = 0;
829 };
830 
831 /** Wrapper class for ref-counted SharedFTFaceData that handles calling the
832  * appropriate ref-counting methods
833  */
834 template <class T>
835 class SharedFTFaceRefCountedData : public SharedFTFaceData {
836  public:
BindData()837   void BindData() { static_cast<T*>(this)->AddRef(); }
ReleaseData()838   void ReleaseData() { static_cast<T*>(this)->Release(); }
839 };
840 
841 /** SharedFTFace is a shared wrapper around an FT_Face. It is ref-counted,
842  * unlike FT_Face itself, so that it may be shared among many users with
843  * RefPtr. Users should take care to lock SharedFTFace before accessing any
844  * FT_Face fields that may change to ensure exclusive access to it. It also
845  * allows backing data's lifetime to be bound to it via SharedFTFaceData so
846  * that the data will not disappear before the face does.
847  */
848 class SharedFTFace : public external::AtomicRefCounted<SharedFTFace> {
849  public:
850   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SharedFTFace)
851 
852   explicit SharedFTFace(FT_Face aFace, SharedFTFaceData* aData = nullptr);
853   virtual ~SharedFTFace();
854 
GetFace()855   FT_Face GetFace() const { return mFace; }
GetData()856   SharedFTFaceData* GetData() const { return mData; }
857 
858   /** Locks the face for exclusive access by a given owner. Returns false if
859    * the given owner is acquiring the lock for the first time, and true if
860    * the owner was the prior owner of the lock. Thus the return value can be
861    * used to do owner-specific initialization of the FT face such as setting
862    * a size or transform that may have been invalidated by a previous owner.
863    * If no owner is given, then the user should avoid modifying any state on
864    * the face so as not to invalidate the prior owner's modification.
865    */
866   bool Lock(void* aOwner = nullptr) {
867     mLock.Lock();
868     return !aOwner || mLastLockOwner.exchange(aOwner) == aOwner;
869   }
Unlock()870   void Unlock() { mLock.Unlock(); }
871 
872   /** Should be called when a lock owner is destroyed so that we don't have
873    * a dangling pointer to a destroyed owner.
874    */
ForgetLockOwner(void * aOwner)875   void ForgetLockOwner(void* aOwner) {
876     if (aOwner) {
877       mLastLockOwner.compareExchange(aOwner, nullptr);
878     }
879   }
880 
881  private:
882   FT_Face mFace;
883   SharedFTFaceData* mData;
884   Mutex mLock;
885   // Remember the last owner of the lock, even after unlocking, to allow users
886   // to avoid reinitializing state on the FT face if the last owner hasn't
887   // changed by the next time it is locked with the same owner.
888   Atomic<void*> mLastLockOwner;
889 };
890 #endif
891 
892 class UnscaledFont : public SupportsThreadSafeWeakPtr<UnscaledFont> {
893  public:
894   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFont)
895   MOZ_DECLARE_THREADSAFEWEAKREFERENCE_TYPENAME(UnscaledFont)
896 
897   virtual ~UnscaledFont();
898 
899   virtual FontType GetType() const = 0;
900 
DeletionCounter()901   static uint32_t DeletionCounter() { return sDeletionCounter; }
902 
903   typedef void (*FontFileDataOutput)(const uint8_t* aData, uint32_t aLength,
904                                      uint32_t aIndex, void* aBaton);
905   typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength,
906                                          void* aBaton);
907   typedef void (*FontDescriptorOutput)(const uint8_t* aData, uint32_t aLength,
908                                        uint32_t aIndex, void* aBaton);
909 
GetFontFileData(FontFileDataOutput,void *)910   virtual bool GetFontFileData(FontFileDataOutput, void*) { return false; }
911 
GetFontInstanceData(FontInstanceDataOutput,void *)912   virtual bool GetFontInstanceData(FontInstanceDataOutput, void*) {
913     return false;
914   }
915 
GetFontDescriptor(FontDescriptorOutput,void *)916   virtual bool GetFontDescriptor(FontDescriptorOutput, void*) { return false; }
917 
CreateScaledFont(Float aGlyphSize,const uint8_t * aInstanceData,uint32_t aInstanceDataLength,const FontVariation * aVariations,uint32_t aNumVariations)918   virtual already_AddRefed<ScaledFont> CreateScaledFont(
919       Float aGlyphSize, const uint8_t* aInstanceData,
920       uint32_t aInstanceDataLength, const FontVariation* aVariations,
921       uint32_t aNumVariations) {
922     return nullptr;
923   }
924 
CreateScaledFontFromWRFont(Float aGlyphSize,const wr::FontInstanceOptions * aOptions,const wr::FontInstancePlatformOptions * aPlatformOptions,const FontVariation * aVariations,uint32_t aNumVariations)925   virtual already_AddRefed<ScaledFont> CreateScaledFontFromWRFont(
926       Float aGlyphSize, const wr::FontInstanceOptions* aOptions,
927       const wr::FontInstancePlatformOptions* aPlatformOptions,
928       const FontVariation* aVariations, uint32_t aNumVariations) {
929     return CreateScaledFont(aGlyphSize, nullptr, 0, aVariations,
930                             aNumVariations);
931   }
932 
933  protected:
934   UnscaledFont() = default;
935 
936  private:
937   static Atomic<uint32_t> sDeletionCounter;
938 };
939 
940 /** This class is an abstraction of a backend/platform specific font object
941  * at a particular size. It is passed into text drawing calls to describe
942  * the font used for the drawing call.
943  */
944 class ScaledFont : public SupportsThreadSafeWeakPtr<ScaledFont> {
945  public:
946   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
947   MOZ_DECLARE_THREADSAFEWEAKREFERENCE_TYPENAME(ScaledFont)
948 
949   virtual ~ScaledFont();
950 
951   virtual FontType GetType() const = 0;
952   virtual Float GetSize() const = 0;
GetDefaultAAMode()953   virtual AntialiasMode GetDefaultAAMode() { return AntialiasMode::DEFAULT; }
954 
DeletionCounter()955   static uint32_t DeletionCounter() { return sDeletionCounter; }
956 
957   /** This allows getting a path that describes the outline of a set of glyphs.
958    * A target is passed in so that the guarantee is made the returned path
959    * can be used with any DrawTarget that has the same backend as the one
960    * passed in.
961    */
962   virtual already_AddRefed<Path> GetPathForGlyphs(
963       const GlyphBuffer& aBuffer, const DrawTarget* aTarget) = 0;
964 
965   /** This copies the path describing the glyphs into a PathBuilder. We use this
966    * API rather than a generic API to append paths because it allows easier
967    * implementation in some backends, and more efficient implementation in
968    * others.
969    */
970   virtual void CopyGlyphsToBuilder(const GlyphBuffer& aBuffer,
971                                    PathBuilder* aBuilder,
972                                    const Matrix* aTransformHint = nullptr) = 0;
973 
974   typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength,
975                                          const FontVariation* aVariations,
976                                          uint32_t aNumVariations, void* aBaton);
977 
GetFontInstanceData(FontInstanceDataOutput,void *)978   virtual bool GetFontInstanceData(FontInstanceDataOutput, void*) {
979     return false;
980   }
981 
GetWRFontInstanceOptions(Maybe<wr::FontInstanceOptions> * aOutOptions,Maybe<wr::FontInstancePlatformOptions> * aOutPlatformOptions,std::vector<FontVariation> * aOutVariations)982   virtual bool GetWRFontInstanceOptions(
983       Maybe<wr::FontInstanceOptions>* aOutOptions,
984       Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
985       std::vector<FontVariation>* aOutVariations) {
986     return false;
987   }
988 
CanSerialize()989   virtual bool CanSerialize() { return false; }
990 
HasVariationSettings()991   virtual bool HasVariationSettings() { return false; }
992 
AddUserData(UserDataKey * key,void * userData,void (* destroy)(void *))993   void AddUserData(UserDataKey* key, void* userData, void (*destroy)(void*)) {
994     mUserData.Add(key, userData, destroy);
995   }
GetUserData(UserDataKey * key)996   void* GetUserData(UserDataKey* key) { return mUserData.Get(key); }
997 
RemoveUserData(UserDataKey * key)998   void RemoveUserData(UserDataKey* key) { mUserData.RemoveAndDestroy(key); }
999 
GetUnscaledFont()1000   const RefPtr<UnscaledFont>& GetUnscaledFont() const { return mUnscaledFont; }
1001 
GetCairoScaledFont()1002   virtual cairo_scaled_font_t* GetCairoScaledFont() { return nullptr; }
1003 
GetSyntheticObliqueAngle()1004   Float GetSyntheticObliqueAngle() const { return mSyntheticObliqueAngle; }
SetSyntheticObliqueAngle(Float aAngle)1005   void SetSyntheticObliqueAngle(Float aAngle) {
1006     mSyntheticObliqueAngle = aAngle;
1007   }
1008 
1009  protected:
ScaledFont(const RefPtr<UnscaledFont> & aUnscaledFont)1010   explicit ScaledFont(const RefPtr<UnscaledFont>& aUnscaledFont)
1011       : mUnscaledFont(aUnscaledFont), mSyntheticObliqueAngle(0.0f) {}
1012 
1013   UserData mUserData;
1014   RefPtr<UnscaledFont> mUnscaledFont;
1015   Float mSyntheticObliqueAngle;
1016 
1017  private:
1018   static Atomic<uint32_t> sDeletionCounter;
1019 };
1020 
1021 /**
1022  * Derived classes hold a native font resource from which to create
1023  * ScaledFonts.
1024  */
1025 class NativeFontResource
1026     : public external::AtomicRefCounted<NativeFontResource> {
1027  public:
1028   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResource)
1029 
1030   /**
1031    * Creates a UnscaledFont using the font corresponding to the index.
1032    *
1033    * @param aIndex index for the font within the resource.
1034    * @param aInstanceData pointer to read-only buffer of any available instance
1035    *                      data.
1036    * @param aInstanceDataLength the size of the instance data.
1037    * @return an already_addrefed UnscaledFont, containing nullptr if failed.
1038    */
1039   virtual already_AddRefed<UnscaledFont> CreateUnscaledFont(
1040       uint32_t aIndex, const uint8_t* aInstanceData,
1041       uint32_t aInstanceDataLength) = 0;
1042 
1043   NativeFontResource(size_t aDataLength);
1044   virtual ~NativeFontResource();
1045 
1046   static void RegisterMemoryReporter();
1047 
1048  private:
1049   size_t mDataLength;
1050 };
1051 
1052 class DrawTargetCapture;
1053 
1054 /** This is the main class used for all the drawing. It is created through the
1055  * factory and accepts drawing commands. The results of drawing to a target
1056  * may be used either through a Snapshot or by flushing the target and directly
1057  * accessing the backing store a DrawTarget was created with.
1058  */
1059 class DrawTarget : public external::AtomicRefCounted<DrawTarget> {
1060  public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget)1061   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget)
1062   DrawTarget()
1063       : mTransformDirty(false),
1064         mPermitSubpixelAA(false),
1065         mFormat(SurfaceFormat::UNKNOWN) {}
1066   virtual ~DrawTarget() = default;
1067 
IsValid()1068   virtual bool IsValid() const { return true; };
1069   virtual DrawTargetType GetType() const = 0;
1070 
1071   virtual BackendType GetBackendType() const = 0;
1072 
IsRecording()1073   virtual bool IsRecording() const { return false; }
IsCaptureDT()1074   virtual bool IsCaptureDT() const { return false; }
1075 
1076   /**
1077    * Returns a SourceSurface which is a snapshot of the current contents of the
1078    * DrawTarget. Multiple calls to Snapshot() without any drawing operations in
1079    * between will normally return the same SourceSurface object.
1080    */
1081   virtual already_AddRefed<SourceSurface> Snapshot() = 0;
1082 
1083   /**
1084    * Returns a SourceSurface which wraps the buffer backing the DrawTarget. The
1085    * contents of the buffer may change if there are drawing operations after
1086    * calling but only guarantees that it reflects the state at the time it was
1087    * called.
1088    */
GetBackingSurface()1089   virtual already_AddRefed<SourceSurface> GetBackingSurface() {
1090     return Snapshot();
1091   }
1092 
1093   // Snapshots the contents and returns an alpha mask
1094   // based on the RGB values.
1095   virtual already_AddRefed<SourceSurface> IntoLuminanceSource(
1096       LuminanceType aLuminanceType, float aOpacity);
1097   virtual IntSize GetSize() const = 0;
GetRect()1098   virtual IntRect GetRect() const { return IntRect(IntPoint(0, 0), GetSize()); }
1099 
1100   /**
1101    * If possible returns the bits to this DrawTarget for direct manipulation.
1102    * While the bits is locked any modifications to this DrawTarget is forbidden.
1103    * Release takes the original data pointer for safety.
1104    */
1105   virtual bool LockBits(uint8_t** aData, IntSize* aSize, int32_t* aStride,
1106                         SurfaceFormat* aFormat, IntPoint* aOrigin = nullptr) {
1107     return false;
1108   }
ReleaseBits(uint8_t * aData)1109   virtual void ReleaseBits(uint8_t* aData) {}
1110 
1111   /** Ensure that the DrawTarget backend has flushed all drawing operations to
1112    * this draw target. This must be called before using the backing surface of
1113    * this draw target outside of GFX 2D code.
1114    */
1115   virtual void Flush() = 0;
1116 
1117   /**
1118    * Realize a DrawTargetCapture onto the draw target.
1119    *
1120    * @param aSource Capture DrawTarget to draw
1121    * @param aTransform Transform to apply when replaying commands
1122    */
1123   virtual void DrawCapturedDT(DrawTargetCapture* aCaptureDT,
1124                               const Matrix& aTransform);
1125 
1126   /**
1127    * Draw a surface to the draw target. Possibly doing partial drawing or
1128    * applying scaling. No sampling happens outside the source.
1129    *
1130    * @param aSurface Source surface to draw
1131    * @param aDest Destination rectangle that this drawing operation should draw
1132    *              to
1133    * @param aSource Source rectangle in aSurface coordinates, this area of
1134    *                aSurface
1135    *                will be stretched to the size of aDest.
1136    * @param aOptions General draw options that are applied to the operation
1137    * @param aSurfOptions DrawSurface options that are applied
1138    */
1139   virtual void DrawSurface(
1140       SourceSurface* aSurface, const Rect& aDest, const Rect& aSource,
1141       const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
1142       const DrawOptions& aOptions = DrawOptions()) = 0;
1143 
1144   virtual void DrawDependentSurface(
1145       uint64_t aId, const Rect& aDest,
1146       const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
1147       const DrawOptions& aOptions = DrawOptions()) {
1148     MOZ_CRASH("GFX: DrawDependentSurface");
1149   }
1150 
1151   /**
1152    * Draw the output of a FilterNode to the DrawTarget.
1153    *
1154    * @param aNode FilterNode to draw
1155    * @param aSourceRect Source rectangle in FilterNode space to draw
1156    * @param aDestPoint Destination point on the DrawTarget to draw the
1157    *                   SourceRectangle of the filter output to
1158    */
1159   virtual void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
1160                           const Point& aDestPoint,
1161                           const DrawOptions& aOptions = DrawOptions()) = 0;
1162 
1163   /**
1164    * Blend a surface to the draw target with a shadow. The shadow is drawn as a
1165    * gaussian blur using a specified sigma. The shadow is clipped to the size
1166    * of the input surface, so the input surface should contain a transparent
1167    * border the size of the approximate coverage of the blur (3 * aSigma).
1168    * NOTE: This function works in device space!
1169    *
1170    * @param aSurface Source surface to draw.
1171    * @param aDest Destination point that this drawing operation should draw to.
1172    * @param aColor Color of the drawn shadow
1173    * @param aOffset Offset of the shadow
1174    * @param aSigma Sigma used for the guassian filter kernel
1175    * @param aOperator Composition operator used
1176    */
1177   virtual void DrawSurfaceWithShadow(SourceSurface* aSurface,
1178                                      const Point& aDest,
1179                                      const DeviceColor& aColor,
1180                                      const Point& aOffset, Float aSigma,
1181                                      CompositionOp aOperator) = 0;
1182 
1183   /**
1184    * Clear a rectangle on the draw target to transparent black. This will
1185    * respect the clipping region and transform.
1186    *
1187    * @param aRect Rectangle to clear
1188    */
1189   virtual void ClearRect(const Rect& aRect) = 0;
1190 
1191   /**
1192    * This is essentially a 'memcpy' between two surfaces. It moves a pixel
1193    * aligned area from the source surface unscaled directly onto the
1194    * drawtarget. This ignores both transform and clip.
1195    *
1196    * @param aSurface Surface to copy from
1197    * @param aSourceRect Source rectangle to be copied
1198    * @param aDest Destination point to copy the surface to
1199    */
1200   virtual void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect,
1201                            const IntPoint& aDestination) = 0;
1202 
1203   /** @see CopySurface
1204    * Same as CopySurface, except uses itself as the source.
1205    *
1206    * Some backends may be able to optimize this better
1207    * than just taking a snapshot and using CopySurface.
1208    */
CopyRect(const IntRect & aSourceRect,const IntPoint & aDestination)1209   virtual void CopyRect(const IntRect& aSourceRect,
1210                         const IntPoint& aDestination) {
1211     RefPtr<SourceSurface> source = Snapshot();
1212     CopySurface(source, aSourceRect, aDestination);
1213   }
1214 
1215   /**
1216    * Fill a rectangle on the DrawTarget with a certain source pattern.
1217    *
1218    * @param aRect Rectangle that forms the mask of this filling operation
1219    * @param aPattern Pattern that forms the source of this filling operation
1220    * @param aOptions Options that are applied to this operation
1221    */
1222   virtual void FillRect(const Rect& aRect, const Pattern& aPattern,
1223                         const DrawOptions& aOptions = DrawOptions()) = 0;
1224 
1225   /**
1226    * Fill a rounded rectangle on the DrawTarget with a certain source pattern.
1227    *
1228    * @param aRect Rounded rectangle that forms the mask of this filling
1229    * operation
1230    * @param aPattern Pattern that forms the source of this filling operation
1231    * @param aOptions Options that are applied to this operation
1232    */
1233   virtual void FillRoundedRect(const RoundedRect& aRect,
1234                                const Pattern& aPattern,
1235                                const DrawOptions& aOptions = DrawOptions());
1236 
1237   /**
1238    * Stroke a rectangle on the DrawTarget with a certain source pattern.
1239    *
1240    * @param aRect Rectangle that forms the mask of this stroking operation
1241    * @param aPattern Pattern that forms the source of this stroking operation
1242    * @param aOptions Options that are applied to this operation
1243    */
1244   virtual void StrokeRect(const Rect& aRect, const Pattern& aPattern,
1245                           const StrokeOptions& aStrokeOptions = StrokeOptions(),
1246                           const DrawOptions& aOptions = DrawOptions()) = 0;
1247 
1248   /**
1249    * Stroke a line on the DrawTarget with a certain source pattern.
1250    *
1251    * @param aStart Starting point of the line
1252    * @param aEnd End point of the line
1253    * @param aPattern Pattern that forms the source of this stroking operation
1254    * @param aOptions Options that are applied to this operation
1255    */
1256   virtual void StrokeLine(const Point& aStart, const Point& aEnd,
1257                           const Pattern& aPattern,
1258                           const StrokeOptions& aStrokeOptions = StrokeOptions(),
1259                           const DrawOptions& aOptions = DrawOptions()) = 0;
1260 
1261   /**
1262    * Stroke a path on the draw target with a certain source pattern.
1263    *
1264    * @param aPath Path that is to be stroked
1265    * @param aPattern Pattern that should be used for the stroke
1266    * @param aStrokeOptions Stroke options used for this operation
1267    * @param aOptions Draw options used for this operation
1268    */
1269   virtual void Stroke(const Path* aPath, const Pattern& aPattern,
1270                       const StrokeOptions& aStrokeOptions = StrokeOptions(),
1271                       const DrawOptions& aOptions = DrawOptions()) = 0;
1272 
1273   /**
1274    * Fill a path on the draw target with a certain source pattern.
1275    *
1276    * @param aPath Path that is to be filled
1277    * @param aPattern Pattern that should be used for the fill
1278    * @param aOptions Draw options used for this operation
1279    */
1280   virtual void Fill(const Path* aPath, const Pattern& aPattern,
1281                     const DrawOptions& aOptions = DrawOptions()) = 0;
1282 
1283   /**
1284    * Fill a series of glyphs on the draw target with a certain source pattern.
1285    */
1286   virtual void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
1287                           const Pattern& aPattern,
1288                           const DrawOptions& aOptions = DrawOptions()) = 0;
1289 
1290   /**
1291    * Stroke a series of glyphs on the draw target with a certain source pattern.
1292    */
1293   virtual void StrokeGlyphs(
1294       ScaledFont* aFont, const GlyphBuffer& aBuffer, const Pattern& aPattern,
1295       const StrokeOptions& aStrokeOptions = StrokeOptions(),
1296       const DrawOptions& aOptions = DrawOptions());
1297 
1298   /**
1299    * This takes a source pattern and a mask, and composites the source pattern
1300    * onto the destination surface using the alpha channel of the mask pattern
1301    * as a mask for the operation.
1302    *
1303    * @param aSource Source pattern
1304    * @param aMask Mask pattern
1305    * @param aOptions Drawing options
1306    */
1307   virtual void Mask(const Pattern& aSource, const Pattern& aMask,
1308                     const DrawOptions& aOptions = DrawOptions()) = 0;
1309 
1310   /**
1311    * This takes a source pattern and a mask, and composites the source pattern
1312    * onto the destination surface using the alpha channel of the mask source.
1313    * The operation is bound by the extents of the mask.
1314    *
1315    * @param aSource Source pattern
1316    * @param aMask Mask surface
1317    * @param aOffset a transformed offset that the surface is masked at
1318    * @param aOptions Drawing options
1319    */
1320   virtual void MaskSurface(const Pattern& aSource, SourceSurface* aMask,
1321                            Point aOffset,
1322                            const DrawOptions& aOptions = DrawOptions()) = 0;
1323 
1324   /**
1325    * Draw aSurface using the 3D transform aMatrix. The DrawTarget's transform
1326    * and clip are applied after the 3D transform.
1327    *
1328    * If the transform fails (i.e. because aMatrix is singular), false is
1329    * returned and nothing is drawn.
1330    */
1331   virtual bool Draw3DTransformedSurface(SourceSurface* aSurface,
1332                                         const Matrix4x4& aMatrix);
1333 
1334   /**
1335    * Push a clip to the DrawTarget.
1336    *
1337    * @param aPath The path to clip to
1338    */
1339   virtual void PushClip(const Path* aPath) = 0;
1340 
1341   /**
1342    * Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
1343    * is specified in user space.
1344    *
1345    * @param aRect The rect to clip to
1346    */
1347   virtual void PushClipRect(const Rect& aRect) = 0;
1348 
1349   /**
1350    * Push a clip region specifed by the union of axis-aligned rectangular
1351    * clips to the DrawTarget. These rectangles are specified in device space.
1352    * This must be balanced by a corresponding call to PopClip within a layer.
1353    *
1354    * @param aRects The rects to clip to
1355    * @param aCount The number of rectangles
1356    */
1357   virtual void PushDeviceSpaceClipRects(const IntRect* aRects, uint32_t aCount);
1358 
1359   /** Pop a clip from the DrawTarget. A pop without a corresponding push will
1360    * be ignored.
1361    */
1362   virtual void PopClip() = 0;
1363 
1364   /**
1365    * Push a 'layer' to the DrawTarget, a layer is a temporary surface that all
1366    * drawing will be redirected to, this is used for example to support group
1367    * opacity or the masking of groups. Clips must be balanced within a layer,
1368    * i.e. between a matching PushLayer/PopLayer pair there must be as many
1369    * PushClip(Rect) calls as there are PopClip calls.
1370    *
1371    * @param aOpaque Whether the layer will be opaque
1372    * @param aOpacity Opacity of the layer
1373    * @param aMask Mask applied to the layer
1374    * @param aMaskTransform Transform applied to the layer mask
1375    * @param aBounds Optional bounds in device space to which the layer is
1376    *                limited in size.
1377    * @param aCopyBackground Whether to copy the background into the layer, this
1378    *                        is only supported when aOpaque is true.
1379    */
1380   virtual void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
1381                          const Matrix& aMaskTransform,
1382                          const IntRect& aBounds = IntRect(),
1383                          bool aCopyBackground = false) {
1384     MOZ_CRASH("GFX: PushLayer");
1385   }
1386 
1387   /**
1388    * Push a 'layer' to the DrawTarget, a layer is a temporary surface that all
1389    * drawing will be redirected to, this is used for example to support group
1390    * opacity or the masking of groups. Clips must be balanced within a layer,
1391    * i.e. between a matching PushLayer/PopLayer pair there must be as many
1392    * PushClip(Rect) calls as there are PopClip calls.
1393    *
1394    * @param aOpaque Whether the layer will be opaque
1395    * @param aOpacity Opacity of the layer
1396    * @param aMask Mask applied to the layer
1397    * @param aMaskTransform Transform applied to the layer mask
1398    * @param aBounds Optional bounds in device space to which the layer is
1399    *                limited in size.
1400    * @param aCopyBackground Whether to copy the background into the layer, this
1401    *                        is only supported when aOpaque is true.
1402    */
1403   virtual void PushLayerWithBlend(bool aOpaque, Float aOpacity,
1404                                   SourceSurface* aMask,
1405                                   const Matrix& aMaskTransform,
1406                                   const IntRect& aBounds = IntRect(),
1407                                   bool aCopyBackground = false,
1408                                   CompositionOp = CompositionOp::OP_OVER) {
1409     MOZ_CRASH("GFX: PushLayerWithBlend");
1410   }
1411 
1412   /**
1413    * This balances a call to PushLayer and proceeds to blend the layer back
1414    * onto the background. This blend will blend the temporary surface back
1415    * onto the target in device space using POINT sampling and operator over.
1416    */
PopLayer()1417   virtual void PopLayer() { MOZ_CRASH("GFX: PopLayer"); }
1418 
1419   /**
1420    * Perform an in-place blur operation. This is only supported on data draw
1421    * targets.
1422    */
1423   virtual void Blur(const AlphaBoxBlur& aBlur);
1424 
1425   /**
1426    * Performs an in-place edge padding operation.
1427    * aRegion is specified in device space.
1428    */
1429   virtual void PadEdges(const IntRegion& aRegion);
1430 
1431   /**
1432    * Performs an in-place buffer unrotation operation.
1433    */
1434   virtual bool Unrotate(IntPoint aRotation);
1435 
1436   /**
1437    * Create a SourceSurface optimized for use with this DrawTarget from
1438    * existing bitmap data in memory.
1439    *
1440    * The SourceSurface does not take ownership of aData, and may be freed at any
1441    * time.
1442    */
1443   virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(
1444       unsigned char* aData, const IntSize& aSize, int32_t aStride,
1445       SurfaceFormat aFormat) const = 0;
1446 
1447   /**
1448    * Create a SourceSurface optimized for use with this DrawTarget from an
1449    * arbitrary SourceSurface type supported by this backend. This may return
1450    * aSourceSurface or some other existing surface.
1451    */
1452   virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(
1453       SourceSurface* aSurface) const = 0;
OptimizeSourceSurfaceForUnknownAlpha(SourceSurface * aSurface)1454   virtual already_AddRefed<SourceSurface> OptimizeSourceSurfaceForUnknownAlpha(
1455       SourceSurface* aSurface) const {
1456     return OptimizeSourceSurface(aSurface);
1457   }
1458 
1459   /**
1460    * Create a SourceSurface for a type of NativeSurface. This may fail if the
1461    * draw target does not know how to deal with the type of NativeSurface passed
1462    * in. If this succeeds, the SourceSurface takes the ownersip of the
1463    * NativeSurface.
1464    */
1465   virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(
1466       const NativeSurface& aSurface) const = 0;
1467 
1468   /**
1469    * Create a DrawTarget whose snapshot is optimized for use with this
1470    * DrawTarget.
1471    */
1472   virtual already_AddRefed<DrawTarget> CreateSimilarDrawTarget(
1473       const IntSize& aSize, SurfaceFormat aFormat) const = 0;
1474 
1475   /**
1476    * Create a DrawTarget whose backing surface is optimized for use with this
1477    * DrawTarget.
1478    */
CreateSimilarDrawTargetWithBacking(const IntSize & aSize,SurfaceFormat aFormat)1479   virtual already_AddRefed<DrawTarget> CreateSimilarDrawTargetWithBacking(
1480       const IntSize& aSize, SurfaceFormat aFormat) const {
1481     return CreateSimilarDrawTarget(aSize, aFormat);
1482   }
1483 
1484   /**
1485    * Create a DrawTarget whose snapshot is optimized for use with this
1486    * DrawTarget and aFilter.
1487    * @param aSource is the FilterNode that that will be attached to this
1488    * surface.
1489    * @param aSourceRect is the source rect that will be passed to DrawFilter
1490    * @param aDestPoint is the dest point that will be passed to DrawFilter.
1491    */
CreateSimilarDrawTargetForFilter(const IntSize & aSize,SurfaceFormat aFormat,FilterNode * aFilter,FilterNode * aSource,const Rect & aSourceRect,const Point & aDestPoint)1492   virtual already_AddRefed<DrawTarget> CreateSimilarDrawTargetForFilter(
1493       const IntSize& aSize, SurfaceFormat aFormat, FilterNode* aFilter,
1494       FilterNode* aSource, const Rect& aSourceRect, const Point& aDestPoint) {
1495     return CreateSimilarDrawTarget(aSize, aFormat);
1496   }
1497 
1498   /**
1499    * Returns false if CreateSimilarDrawTarget would return null with the same
1500    * parameters. May return true even in cases where CreateSimilarDrawTarget
1501    * return null (i.e. this function returning false has meaning, but returning
1502    * true doesn't guarantee anything).
1503    */
CanCreateSimilarDrawTarget(const IntSize & aSize,SurfaceFormat aFormat)1504   virtual bool CanCreateSimilarDrawTarget(const IntSize& aSize,
1505                                           SurfaceFormat aFormat) const {
1506     return true;
1507   }
1508 
1509   /**
1510    * Create a draw target optimized for drawing a shadow.
1511    *
1512    * Note that aSigma is the blur radius that must be used when we draw the
1513    * shadow. Also note that this doesn't affect the size of the allocated
1514    * surface, the caller is still responsible for including the shadow area in
1515    * its size.
1516    */
CreateShadowDrawTarget(const IntSize & aSize,SurfaceFormat aFormat,float aSigma)1517   virtual already_AddRefed<DrawTarget> CreateShadowDrawTarget(
1518       const IntSize& aSize, SurfaceFormat aFormat, float aSigma) const {
1519     return CreateSimilarDrawTarget(aSize, aFormat);
1520   }
1521 
1522   /**
1523    * Create a similar DrawTarget in the same space as this DrawTarget whose
1524    * device size may be clipped based on the active clips intersected with
1525    * aBounds (if it is not empty).
1526    */
1527   virtual RefPtr<DrawTarget> CreateClippedDrawTarget(const Rect& aBounds,
1528                                                      SurfaceFormat aFormat) = 0;
1529 
1530   /**
1531    * Create a similar draw target, but if the draw target is not backed by a
1532    * raster backend (for example, it is capturing or recording), force it to
1533    * create a raster target instead. This is intended for code that wants to
1534    * cache pixels, and would have no effect if it were caching a recording.
1535    */
CreateSimilarRasterTarget(const IntSize & aSize,SurfaceFormat aFormat)1536   virtual RefPtr<DrawTarget> CreateSimilarRasterTarget(
1537       const IntSize& aSize, SurfaceFormat aFormat) const {
1538     return CreateSimilarDrawTarget(aSize, aFormat);
1539   }
1540 
1541   /**
1542    * Create a path builder with the specified fillmode.
1543    *
1544    * We need the fill mode up front because of Direct2D.
1545    * ID2D1SimplifiedGeometrySink requires the fill mode
1546    * to be set before calling BeginFigure().
1547    */
1548   virtual already_AddRefed<PathBuilder> CreatePathBuilder(
1549       FillRule aFillRule = FillRule::FILL_WINDING) const = 0;
1550 
1551   /**
1552    * Create a GradientStops object that holds information about a set of
1553    * gradient stops, this object is required for linear or radial gradient
1554    * patterns to represent the color stops in the gradient.
1555    *
1556    * @param aStops An array of gradient stops
1557    * @param aNumStops Number of stops in the array aStops
1558    * @param aExtendNone This describes how to extend the stop color outside of
1559    * the gradient area.
1560    */
1561   virtual already_AddRefed<GradientStops> CreateGradientStops(
1562       GradientStop* aStops, uint32_t aNumStops,
1563       ExtendMode aExtendMode = ExtendMode::CLAMP) const = 0;
1564 
1565   /**
1566    * Create a FilterNode object that can be used to apply a filter to various
1567    * inputs.
1568    *
1569    * @param aType Type of filter node to be created.
1570    */
1571   virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) = 0;
1572 
GetTransform()1573   Matrix GetTransform() const { return mTransform; }
1574 
1575   /**
1576    * Set a transform on the surface, this transform is applied at drawing time
1577    * to both the mask and source of the operation.
1578    *
1579    * Performance note: For some backends it is expensive to change the current
1580    * transform (because transforms affect a lot of the parts of the pipeline,
1581    * so new transform change can result in a pipeline flush).  To get around
1582    * this, DrawTarget implementations buffer transform changes and try to only
1583    * set the current transform on the backend when required.  That tracking has
1584    * its own performance impact though, and ideally callers would be smart
1585    * enough not to require it.  At a future date this method may stop this
1586    * doing transform buffering so, if you're a consumer, please try to be smart
1587    * about calling this method as little as possible.  For example, instead of
1588    * concatenating a translation onto the current transform then calling
1589    * FillRect, try to integrate the translation into FillRect's aRect
1590    * argument's x/y offset.
1591    */
SetTransform(const Matrix & aTransform)1592   virtual void SetTransform(const Matrix& aTransform) {
1593     mTransform = aTransform;
1594     mTransformDirty = true;
1595   }
1596 
ConcatTransform(const Matrix & aTransform)1597   inline void ConcatTransform(const Matrix& aTransform) {
1598     SetTransform(aTransform * Matrix(GetTransform()));
1599   }
1600 
GetFormat()1601   SurfaceFormat GetFormat() const { return mFormat; }
1602 
1603   /** Tries to get a native surface for a DrawTarget, this may fail if the
1604    * draw target cannot convert to this surface type.
1605    */
GetNativeSurface(NativeSurfaceType aType)1606   virtual void* GetNativeSurface(NativeSurfaceType aType) { return nullptr; }
1607 
IsDualDrawTarget()1608   virtual bool IsDualDrawTarget() const { return false; }
IsTiledDrawTarget()1609   virtual bool IsTiledDrawTarget() const { return false; }
SupportsRegionClipping()1610   virtual bool SupportsRegionClipping() const { return true; }
1611 
AddUserData(UserDataKey * key,void * userData,void (* destroy)(void *))1612   void AddUserData(UserDataKey* key, void* userData, void (*destroy)(void*)) {
1613     mUserData.Add(key, userData, destroy);
1614   }
GetUserData(UserDataKey * key)1615   void* GetUserData(UserDataKey* key) const { return mUserData.Get(key); }
RemoveUserData(UserDataKey * key)1616   void* RemoveUserData(UserDataKey* key) { return mUserData.Remove(key); }
1617 
1618   /** Within this rectangle all pixels will be opaque by the time the result of
1619    * this DrawTarget is first used for drawing. Either by the underlying surface
1620    * being used as an input to external drawing, or Snapshot() being called.
1621    * This rectangle is specified in device space.
1622    */
SetOpaqueRect(const IntRect & aRect)1623   void SetOpaqueRect(const IntRect& aRect) { mOpaqueRect = aRect; }
1624 
GetOpaqueRect()1625   const IntRect& GetOpaqueRect() const { return mOpaqueRect; }
1626 
IsCurrentGroupOpaque()1627   virtual bool IsCurrentGroupOpaque() {
1628     return GetFormat() == SurfaceFormat::B8G8R8X8;
1629   }
1630 
SetPermitSubpixelAA(bool aPermitSubpixelAA)1631   virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) {
1632     mPermitSubpixelAA = aPermitSubpixelAA;
1633   }
1634 
GetPermitSubpixelAA()1635   bool GetPermitSubpixelAA() { return mPermitSubpixelAA; }
1636 
1637   /**
1638    * Mark the end of an Item in a DrawTargetRecording. These markers
1639    * are used for merging recordings together.
1640    *
1641    * This should only be called on the 'root' DrawTargetRecording.
1642    * Calling it on a child DrawTargetRecordings will cause confusion.
1643    *
1644    * Note: this is a bit of a hack. It might be better to just recreate
1645    * the DrawTargetRecording.
1646    */
FlushItem(const IntRect & aBounds)1647   virtual void FlushItem(const IntRect& aBounds) {}
1648 
1649   /**
1650    * Ensures that no snapshot is still pointing to this DrawTarget's surface
1651    * data.
1652    *
1653    * This can be useful if the DrawTarget is wrapped around data that it does
1654    * not own, and for some reason the owner of the data has to make it
1655    * temporarily unavailable without the DrawTarget knowing about it. This can
1656    * cause costly surface copies, so it should not be used without a a good
1657    * reason.
1658    */
1659   virtual void DetachAllSnapshots() = 0;
1660 
1661  protected:
1662   UserData mUserData;
1663   Matrix mTransform;
1664   IntRect mOpaqueRect;
1665   bool mTransformDirty : 1;
1666   bool mPermitSubpixelAA : 1;
1667 
1668   SurfaceFormat mFormat;
1669 };
1670 
1671 class DrawTargetCapture : public DrawTarget {
1672  public:
IsCaptureDT()1673   bool IsCaptureDT() const override { return true; }
1674 
1675   virtual bool IsEmpty() const = 0;
1676   virtual void Dump() = 0;
1677 };
1678 
1679 class DrawEventRecorder : public RefCounted<DrawEventRecorder> {
1680  public:
1681   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorder)
1682   // returns true if there were any items in the recording
1683   virtual bool Finish() = 0;
1684   virtual ~DrawEventRecorder() = default;
1685 };
1686 
1687 struct Tile {
1688   RefPtr<DrawTarget> mDrawTarget;
1689   IntPoint mTileOrigin;
1690 };
1691 
1692 struct TileSet {
1693   Tile* mTiles;
1694   size_t mTileCount;
1695 };
1696 
1697 struct Config {
1698   LogForwarder* mLogForwarder;
1699   int32_t mMaxTextureSize;
1700   int32_t mMaxAllocSize;
1701 
ConfigConfig1702   Config()
1703       : mLogForwarder(nullptr),
1704         mMaxTextureSize(kReasonableSurfaceSize),
1705         mMaxAllocSize(52000000) {}
1706 };
1707 
1708 class GFX2D_API Factory {
1709   using char_type = filesystem::Path::value_type;
1710 
1711  public:
1712   static void Init(const Config& aConfig);
1713   static void ShutDown();
1714 
1715   static bool HasSSE2();
1716   static bool HasSSE4();
1717 
1718   /**
1719    * Returns false if any of the following are true:
1720    *
1721    *   - the width/height of |sz| are less than or equal to zero
1722    *   - the width/height of |sz| are greater than |limit|
1723    *   - the number of bytes that need to be allocated for the surface is too
1724    *     big to fit in an int32_t, or bigger than |allocLimit|, if specifed
1725    *
1726    * To calculate the number of bytes that need to be allocated for the surface
1727    * this function makes the conservative assumption that there need to be
1728    * 4 bytes-per-pixel, and the stride alignment is 16 bytes.
1729    *
1730    * The reason for using int32_t rather than uint32_t is again to be
1731    * conservative; some code has in the past and may in the future use signed
1732    * integers to store buffer lengths etc.
1733    */
1734   static bool CheckSurfaceSize(const IntSize& sz, int32_t limit = 0,
1735                                int32_t allocLimit = 0);
1736 
1737   /**
1738    * Make sure that the given buffer size doesn't exceed the allocation limit.
1739    */
1740   static bool CheckBufferSize(int32_t bufSize);
1741 
1742   /** Make sure the given dimension satisfies the CheckSurfaceSize and is
1743    * within 8k limit.  The 8k value is chosen a bit randomly.
1744    */
1745   static bool ReasonableSurfaceSize(const IntSize& aSize);
1746 
1747   static bool AllowedSurfaceSize(const IntSize& aSize);
1748 
1749   static already_AddRefed<DrawTarget> CreateDrawTargetForCairoSurface(
1750       cairo_surface_t* aSurface, const IntSize& aSize,
1751       SurfaceFormat* aFormat = nullptr);
1752 
1753   static already_AddRefed<SourceSurface> CreateSourceSurfaceForCairoSurface(
1754       cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat aFormat);
1755 
1756   static already_AddRefed<DrawTarget> CreateDrawTarget(BackendType aBackend,
1757                                                        const IntSize& aSize,
1758                                                        SurfaceFormat aFormat);
1759 
1760   /**
1761    * Create a simple PathBuilder, which uses SKIA backend. If USE_SKIA is not
1762    * defined, this returns nullptr;
1763    */
1764   static already_AddRefed<PathBuilder> CreateSimplePathBuilder();
1765 
1766   /**
1767    * Create a DrawTarget that captures the drawing commands to eventually be
1768    * replayed onto the DrawTarget provided. An optional byte size can be
1769    * provided as a limit for the CaptureCommandList. When the limit is reached,
1770    * the CaptureCommandList will be replayed to the target and then cleared.
1771    *
1772    * @param aSize Size of the area this DT will capture.
1773    * @param aFlushBytes The byte limit at which to flush the CaptureCommandList
1774    */
1775   static already_AddRefed<DrawTargetCapture> CreateCaptureDrawTargetForTarget(
1776       gfx::DrawTarget* aTarget, size_t aFlushBytes = 0);
1777 
1778   /**
1779    * Create a DrawTarget that captures the drawing commands and can be replayed
1780    * onto a compatible DrawTarget afterwards.
1781    *
1782    * @param aSize Size of the area this DT will capture.
1783    */
1784   static already_AddRefed<DrawTargetCapture> CreateCaptureDrawTarget(
1785       BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat);
1786 
1787   static already_AddRefed<DrawTargetCapture> CreateCaptureDrawTargetForData(
1788       BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat,
1789       int32_t aStride, size_t aSurfaceAllocationSize);
1790 
1791   static already_AddRefed<DrawTarget> CreateWrapAndRecordDrawTarget(
1792       DrawEventRecorder* aRecorder, DrawTarget* aDT);
1793 
1794   static already_AddRefed<DrawTarget> CreateRecordingDrawTarget(
1795       DrawEventRecorder* aRecorder, DrawTarget* aDT, IntRect aRect);
1796 
1797   static already_AddRefed<DrawTarget> CreateDrawTargetForData(
1798       BackendType aBackend, unsigned char* aData, const IntSize& aSize,
1799       int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
1800 
1801 #ifdef XP_DARWIN
1802   static already_AddRefed<ScaledFont> CreateScaledFontForMacFont(
1803       CGFontRef aCGFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
1804       const DeviceColor& aFontSmoothingBackgroundColor,
1805       bool aUseFontSmoothing = true, bool aApplySyntheticBold = false);
1806 #endif
1807 
1808 #ifdef MOZ_WIDGET_GTK
1809   static already_AddRefed<ScaledFont> CreateScaledFontForFontconfigFont(
1810       const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
1811       RefPtr<SharedFTFace> aFace, FcPattern* aPattern);
1812 #endif
1813 
1814 #ifdef MOZ_WIDGET_ANDROID
1815   static already_AddRefed<ScaledFont> CreateScaledFontForFreeTypeFont(
1816       const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
1817       RefPtr<SharedFTFace> aFace, bool aApplySyntheticBold = false);
1818 #endif
1819 
1820   /**
1821    * This creates a NativeFontResource from TrueType data.
1822    *
1823    * @param aData Pointer to the data
1824    * @param aSize Size of the TrueType data
1825    * @param aFontType Type of NativeFontResource that should be created.
1826    * @param aFontContext Optional native font context to be used to create the
1827    *                              NativeFontResource.
1828    * @return a NativeFontResource of nullptr if failed.
1829    */
1830   static already_AddRefed<NativeFontResource> CreateNativeFontResource(
1831       uint8_t* aData, uint32_t aSize, FontType aFontType,
1832       void* aFontContext = nullptr);
1833 
1834   /**
1835    * This creates an unscaled font of the given type based on font descriptor
1836    * data retrieved from ScaledFont::GetFontDescriptor.
1837    */
1838   static already_AddRefed<UnscaledFont> CreateUnscaledFontFromFontDescriptor(
1839       FontType aType, const uint8_t* aData, uint32_t aDataLength,
1840       uint32_t aIndex);
1841 
1842   /**
1843    * This creates a simple data source surface for a certain size. It allocates
1844    * new memory for the surface. This memory is freed when the surface is
1845    * destroyed.  The caller is responsible for handing the case where nullptr
1846    * is returned. The surface is not zeroed unless requested.
1847    */
1848   static already_AddRefed<DataSourceSurface> CreateDataSourceSurface(
1849       const IntSize& aSize, SurfaceFormat aFormat, bool aZero = false);
1850 
1851   /**
1852    * This creates a simple data source surface for a certain size with a
1853    * specific stride, which must be large enough to fit all pixels.
1854    * It allocates new memory for the surface. This memory is freed when
1855    * the surface is destroyed.  The caller is responsible for handling the case
1856    * where nullptr is returned. The surface is not zeroed unless requested.
1857    */
1858   static already_AddRefed<DataSourceSurface> CreateDataSourceSurfaceWithStride(
1859       const IntSize& aSize, SurfaceFormat aFormat, int32_t aStride,
1860       bool aZero = false);
1861 
1862   typedef void (*SourceSurfaceDeallocator)(void* aClosure);
1863 
1864   /**
1865    * This creates a simple data source surface for some existing data. It will
1866    * wrap this data and the data for this source surface.
1867    *
1868    * We can provide a custom destroying function for |aData|. This will be
1869    * called in the surface dtor using |aDeallocator| and the |aClosure|. If
1870    * there are errors during construction(return a nullptr surface), the caller
1871    * is responsible for the deallocation.
1872    *
1873    * If there is no destroying function, the caller is responsible for
1874    * deallocating the aData memory only after destruction of this
1875    * DataSourceSurface.
1876    */
1877   static already_AddRefed<DataSourceSurface> CreateWrappingDataSourceSurface(
1878       uint8_t* aData, int32_t aStride, const IntSize& aSize,
1879       SurfaceFormat aFormat, SourceSurfaceDeallocator aDeallocator = nullptr,
1880       void* aClosure = nullptr);
1881 
1882   static void CopyDataSourceSurface(DataSourceSurface* aSource,
1883                                     DataSourceSurface* aDest);
1884 
1885   static already_AddRefed<DrawEventRecorder> CreateEventRecorderForFile(
1886       const char_type* aFilename);
1887 
1888   static void SetGlobalEventRecorder(DrawEventRecorder* aRecorder);
1889 
1890   static uint32_t GetMaxSurfaceSize(BackendType aType);
1891 
GetLogForwarder()1892   static LogForwarder* GetLogForwarder() {
1893     return sConfig ? sConfig->mLogForwarder : nullptr;
1894   }
1895 
1896  private:
1897   static Config* sConfig;
1898 
1899  public:
1900   static void PurgeAllCaches();
1901 
1902   static already_AddRefed<DrawTarget> CreateDualDrawTarget(DrawTarget* targetA,
1903                                                            DrawTarget* targetB);
1904 
1905   static already_AddRefed<SourceSurface> CreateDualSourceSurface(
1906       SourceSurface* sourceA, SourceSurface* sourceB);
1907 
1908   /*
1909    * This creates a new tiled DrawTarget. When a tiled drawtarget is used the
1910    * drawing is distributed over number of tiles which may each hold an
1911    * individual offset. The tiles in the set must each have the same backend
1912    * and format.
1913    */
1914   static already_AddRefed<DrawTarget> CreateTiledDrawTarget(
1915       const TileSet& aTileSet);
1916   static already_AddRefed<DrawTarget> CreateOffsetDrawTarget(
1917       DrawTarget* aDrawTarget, IntPoint aTileOrigin);
1918 
1919   static bool DoesBackendSupportDataDrawtarget(BackendType aType);
1920 
1921   static void SetBGRSubpixelOrder(bool aBGR);
1922   static bool GetBGRSubpixelOrder();
1923 
1924  private:
1925   static bool mBGRSubpixelOrder;
1926 
1927  public:
1928 #ifdef USE_SKIA
1929   static already_AddRefed<DrawTarget> CreateDrawTargetWithSkCanvas(
1930       SkCanvas* aCanvas);
1931 #endif
1932 
1933 #ifdef MOZ_ENABLE_FREETYPE
1934   static void SetFTLibrary(FT_Library aFTLibrary);
1935   static FT_Library GetFTLibrary();
1936 
1937   static FT_Library NewFTLibrary();
1938   static void ReleaseFTLibrary(FT_Library aFTLibrary);
1939   static void LockFTLibrary(FT_Library aFTLibrary);
1940   static void UnlockFTLibrary(FT_Library aFTLibrary);
1941 
1942   static FT_Face NewFTFace(FT_Library aFTLibrary, const char* aFileName,
1943                            int aFaceIndex);
1944   static already_AddRefed<SharedFTFace> NewSharedFTFace(FT_Library aFTLibrary,
1945                                                         const char* aFilename,
1946                                                         int aFaceIndex);
1947   static FT_Face NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData,
1948                                    size_t aDataSize, int aFaceIndex);
1949   static already_AddRefed<SharedFTFace> NewSharedFTFaceFromData(
1950       FT_Library aFTLibrary, const uint8_t* aData, size_t aDataSize,
1951       int aFaceIndex, SharedFTFaceData* aSharedData = nullptr);
1952   static void ReleaseFTFace(FT_Face aFace);
1953   static FT_Error LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex,
1954                               int32_t aFlags);
1955 
1956  private:
1957   static FT_Library mFTLibrary;
1958   static StaticMutex mFTLock;
1959 
1960  public:
1961 #endif
1962 
1963 #ifdef WIN32
1964   static already_AddRefed<DrawTarget> CreateDrawTargetForD3D11Texture(
1965       ID3D11Texture2D* aTexture, SurfaceFormat aFormat);
1966 
1967   /*
1968    * Attempts to create and install a D2D1 device from the supplied Direct3D11
1969    * device. Returns true on success, or false on failure and leaves the
1970    * D2D1/Direct3D11 devices unset.
1971    */
1972   static bool SetDirect3D11Device(ID3D11Device* aDevice);
1973   static RefPtr<ID3D11Device> GetDirect3D11Device();
1974   static RefPtr<ID2D1Device> GetD2D1Device(uint32_t* aOutSeqNo = nullptr);
1975   static bool HasD2D1Device();
1976   static RefPtr<IDWriteFactory> GetDWriteFactory();
1977   static RefPtr<IDWriteFactory> EnsureDWriteFactory();
1978   static bool SupportsD2D1();
1979   static RefPtr<IDWriteFontCollection> GetDWriteSystemFonts(
1980       bool aUpdate = false);
1981   static RefPtr<ID2D1DeviceContext> GetD2DDeviceContext();
1982 
1983   static uint64_t GetD2DVRAMUsageDrawTarget();
1984   static uint64_t GetD2DVRAMUsageSourceSurface();
1985   static void D2DCleanup();
1986 
1987   static already_AddRefed<ScaledFont> CreateScaledFontForDWriteFont(
1988       IDWriteFontFace* aFontFace, const gfxFontStyle* aStyle,
1989       const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
1990       bool aUseEmbeddedBitmap, int aRenderingMode,
1991       IDWriteRenderingParams* aParams, Float aGamma, Float aContrast,
1992       Float aClearTypeLevel);
1993 
1994   static already_AddRefed<ScaledFont> CreateScaledFontForGDIFont(
1995       const void* aLogFont, const RefPtr<UnscaledFont>& aUnscaledFont,
1996       Float aSize);
1997 
1998   static void SetSystemTextQuality(uint8_t aQuality);
1999 
2000   static already_AddRefed<DataSourceSurface>
2001   CreateBGRA8DataSourceSurfaceForD3D11Texture(ID3D11Texture2D* aSrcTexture);
2002 
2003   static bool ReadbackTexture(layers::TextureData* aDestCpuTexture,
2004                               ID3D11Texture2D* aSrcTexture);
2005 
2006   static bool ReadbackTexture(DataSourceSurface* aDestCpuTexture,
2007                               ID3D11Texture2D* aSrcTexture);
2008 
2009  private:
2010   static StaticRefPtr<ID2D1Device> mD2D1Device;
2011   static StaticRefPtr<ID3D11Device> mD3D11Device;
2012   static StaticRefPtr<IDWriteFactory> mDWriteFactory;
2013   static bool mDWriteFactoryInitialized;
2014   static StaticRefPtr<IDWriteFontCollection> mDWriteSystemFonts;
2015   static StaticRefPtr<ID2D1DeviceContext> mMTDC;
2016   static StaticRefPtr<ID2D1DeviceContext> mOffMTDC;
2017 
2018   static bool ReadbackTexture(uint8_t* aDestData, int32_t aDestStride,
2019                               ID3D11Texture2D* aSrcTexture);
2020 
2021   // DestTextureT can be TextureData or DataSourceSurface.
2022   template <typename DestTextureT>
2023   static bool ConvertSourceAndRetryReadback(DestTextureT* aDestCpuTexture,
2024                                             ID3D11Texture2D* aSrcTexture);
2025 
2026  protected:
2027   // This guards access to the singleton devices above, as well as the
2028   // singleton devices in DrawTargetD2D1.
2029   static StaticMutex mDeviceLock;
2030   // This synchronizes access between different D2D drawtargets and their
2031   // implied dependency graph.
2032   static StaticMutex mDTDependencyLock;
2033 
2034   friend class DrawTargetD2D1;
2035 #endif  // WIN32
2036 
2037  private:
2038   static DrawEventRecorder* mRecorder;
2039 };
2040 
2041 class MOZ_RAII AutoSerializeWithMoz2D final {
2042  public:
2043   explicit AutoSerializeWithMoz2D(BackendType aBackendType);
2044   ~AutoSerializeWithMoz2D();
2045 
2046  private:
2047 #if defined(WIN32)
2048   RefPtr<ID2D1Multithread> mMT;
2049 #endif
2050 };
2051 
2052 }  // namespace gfx
2053 }  // namespace mozilla
2054 
2055 #endif  // _MOZILLA_GFX_2D_H
2056