tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

2D.h (90156B)


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