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