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/. */
7 #ifndef _MOZILLA_GFX_2D_H
8 #define _MOZILLA_GFX_2D_H
14 #include "Quaternion.h"
16 #include "FontVariation.h"
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"
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
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"
37 #include "mozilla/DebugOnly.h"
39 #include "nsRegionFwd.h"
41 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
42 # ifndef MOZ_ENABLE_FREETYPE
43 # define MOZ_ENABLE_FREETYPE
47 struct _cairo_surface
;
48 typedef _cairo_surface cairo_surface_t
;
50 struct _cairo_scaled_font
;
51 typedef _cairo_scaled_font cairo_scaled_font_t
;
53 struct FT_LibraryRec_
;
54 typedef FT_LibraryRec_
* FT_Library
;
57 typedef FT_FaceRec_
* FT_Face
;
62 typedef _FcPattern FcPattern
;
64 struct ID3D11Texture2D
;
67 struct ID2D1DeviceContext
;
68 struct ID2D1Multithread
;
69 struct IDWriteFactory
;
70 struct IDWriteRenderingParams
;
71 struct IDWriteFontFace
;
72 struct IDWriteFontCollection
;
78 typedef struct CGContext
* CGContextRef
;
81 typedef CGFont
* CGFontRef
;
89 class SurfaceDescriptorBuffer
;
94 struct FontInstanceOptions
;
95 struct FontInstancePlatformOptions
;
108 class DataSourceSurface
;
110 class DrawEventRecorder
;
114 struct NativeSurface
{
115 NativeSurfaceType mType
;
116 SurfaceFormat mFormat
;
122 * This structure is used to send draw options that are universal to all drawing
126 /// For constructor parameter description, see member data documentation.
127 explicit DrawOptions(Float aAlpha
= 1.0f
,
128 CompositionOp aCompositionOp
= CompositionOp::OP_OVER
,
129 AntialiasMode aAntialiasMode
= AntialiasMode::DEFAULT
)
131 mCompositionOp(aCompositionOp
),
132 mAntialiasMode(aAntialiasMode
) {}
134 Float mAlpha
; /**< Alpha value by which the mask generated by this
135 operation is multiplied. */
136 CompositionOp mCompositionOp
; /**< The operator that indicates how the source
137 and destination patterns are blended. */
138 AntialiasMode mAntialiasMode
; /**< The AntiAlias mode used for this drawing
142 struct StoredStrokeOptions
;
145 * This structure is used to send stroke options that are used in stroking
148 struct StrokeOptions
{
149 /// For constructor parameter description, see member data documentation.
150 explicit StrokeOptions(Float aLineWidth
= 1.0f
,
151 JoinStyle aLineJoin
= JoinStyle::MITER_OR_BEVEL
,
152 CapStyle aLineCap
= CapStyle::BUTT
,
153 Float aMiterLimit
= 10.0f
, size_t aDashLength
= 0,
154 const Float
* aDashPattern
= 0, Float aDashOffset
= 0.f
)
155 : mLineWidth(aLineWidth
),
156 mMiterLimit(aMiterLimit
),
157 mDashPattern(aDashLength
> 0 ? aDashPattern
: 0),
158 mDashLength(aDashLength
),
159 mDashOffset(aDashOffset
),
160 mLineJoin(aLineJoin
),
162 MOZ_ASSERT(aDashLength
== 0 || aDashPattern
);
165 Float mLineWidth
; //!< Width of the stroke in userspace.
166 Float mMiterLimit
; //!< Miter limit in units of linewidth
167 const Float
* mDashPattern
; /**< Series of on/off userspace lengths defining
168 dash. Owned by the caller; must live at least as
169 long as this StrokeOptions.
170 mDashPattern != null <=> mDashLength > 0. */
171 size_t mDashLength
; //!< Number of on/off lengths in mDashPattern.
172 Float mDashOffset
; /**< Userspace offset within mDashPattern at which
174 JoinStyle mLineJoin
; //!< Join style used for joining lines.
175 CapStyle mLineCap
; //!< Cap style used for capping lines.
177 StoredStrokeOptions
* Clone() const;
179 bool operator==(const StrokeOptions
& aOther
) const {
180 return mLineWidth
== aOther
.mLineWidth
&&
181 mMiterLimit
== aOther
.mMiterLimit
&&
182 mDashLength
== aOther
.mDashLength
&&
183 (!mDashLength
|| (mDashPattern
&& aOther
.mDashPattern
&&
184 !memcmp(mDashPattern
, aOther
.mDashPattern
,
185 mDashLength
* sizeof(Float
)))) &&
186 mDashOffset
== aOther
.mDashOffset
&& mLineJoin
== aOther
.mLineJoin
&&
187 mLineCap
== aOther
.mLineCap
;
192 * Heap-allocated variation of StrokeOptions that ensures dash patterns are
193 * properly allocated and destroyed even if the source was stack-allocated.
195 struct StoredStrokeOptions
: public StrokeOptions
{
196 explicit StoredStrokeOptions(const StrokeOptions
& aOptions
)
197 : StrokeOptions(aOptions
) {
199 Float
* pattern
= new Float
[mDashLength
];
200 memcpy(pattern
, mDashPattern
, mDashLength
* sizeof(Float
));
201 mDashPattern
= pattern
;
205 ~StoredStrokeOptions() {
207 delete[] mDashPattern
;
212 inline StoredStrokeOptions
* StrokeOptions::Clone() const {
213 return new StoredStrokeOptions(*this);
217 * This structure supplies additional options for calls to DrawSurface.
219 struct DrawSurfaceOptions
{
220 /// For constructor parameter description, see member data documentation.
221 explicit DrawSurfaceOptions(
222 SamplingFilter aSamplingFilter
= SamplingFilter::LINEAR
,
223 SamplingBounds aSamplingBounds
= SamplingBounds::UNBOUNDED
)
224 : mSamplingFilter(aSamplingFilter
), mSamplingBounds(aSamplingBounds
) {}
227 mSamplingFilter
; /**< SamplingFilter used when resampling source surface
228 region to the destination region. */
229 SamplingBounds mSamplingBounds
; /**< This indicates whether the implementation
230 is allowed to sample pixels outside the
231 source rectangle as specified in
232 DrawSurface on the surface. */
236 * ShadowOptions supplies options necessary for describing the appearance of a
237 * a shadow in draw calls that use shadowing.
239 struct ShadowOptions
{
240 explicit ShadowOptions(const DeviceColor
& aColor
= DeviceColor(0.0f
, 0.0f
,
242 const Point
& aOffset
= Point(), Float aSigma
= 0.0f
)
243 : mColor(aColor
), mOffset(aOffset
), mSigma(aSigma
) {}
245 DeviceColor mColor
; /**< Color of the drawn shadow. */
246 Point mOffset
; /**< Offset of the shadow. */
247 Float mSigma
; /**< Sigma used for the Gaussian filter kernel. */
249 int32_t BlurRadius() const;
253 * This class is used to store gradient stops, it can only be used with a
254 * matching DrawTarget. Not adhering to this condition will make a draw call
257 class GradientStops
: public SupportsThreadSafeWeakPtr
<GradientStops
> {
259 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops
)
260 virtual ~GradientStops() = default;
262 virtual BackendType
GetBackendType() const = 0;
263 virtual bool IsValid() const { return true; }
266 GradientStops() = default;
270 * This is the base class for 'patterns'. Patterns describe the pixels used as
271 * the source for a masked composition operation that is done by the different
272 * drawing commands. These objects are not backend specific, however for
273 * example the gradient stops on a gradient pattern can be backend specific.
277 virtual ~Pattern() = default;
279 virtual PatternType
GetType() const = 0;
281 /** Instantiate a new clone with the same pattern type and values. Any
282 * internal strong references will be converted to weak references. */
283 virtual Pattern
* CloneWeak() const { return nullptr; }
285 /** Whether the pattern holds an internal weak reference. */
286 virtual bool IsWeak() const { return false; }
288 /** Whether any internal weak references still point to a target. */
289 virtual bool IsValid() const { return true; }
291 /** Determine if the pattern type and values exactly match. */
292 virtual bool operator==(const Pattern
& aOther
) const = 0;
294 bool operator!=(const Pattern
& aOther
) const { return !(*this == aOther
); }
299 // Utility functions to check if a weak reference is still valid.
300 template <typename T
>
301 static inline bool IsRefValid(const RefPtr
<T
>& aPtr
) {
302 // RefPtrs are always valid.
306 template <typename T
>
307 static inline bool IsRefValid(const ThreadSafeWeakPtr
<T
>& aPtr
) {
308 // Weak refs are only valid if they aren't dead.
309 return !aPtr
.IsDead();
313 class ColorPattern
: public Pattern
{
315 // Explicit because consumers should generally use ToDeviceColor when
316 // creating a ColorPattern.
317 explicit ColorPattern(const DeviceColor
& aColor
) : mColor(aColor
) {}
319 PatternType
GetType() const override
{ return PatternType::COLOR
; }
321 Pattern
* CloneWeak() const override
{ return new ColorPattern(mColor
); }
323 bool operator==(const Pattern
& aOther
) const override
{
324 if (aOther
.GetType() != PatternType::COLOR
) {
327 const ColorPattern
& other
= static_cast<const ColorPattern
&>(aOther
);
328 return mColor
== other
.mColor
;
335 * This class is used for Linear Gradient Patterns, the gradient stops are
336 * stored in a separate object and are backend dependent. This class itself
337 * may be used on the stack.
339 template <template <typename
> typename REF
= RefPtr
>
340 class LinearGradientPatternT
: public Pattern
{
341 typedef LinearGradientPatternT
<ThreadSafeWeakPtr
> Weak
;
344 /// For constructor parameter description, see member data documentation.
345 LinearGradientPatternT(const Point
& aBegin
, const Point
& aEnd
,
346 RefPtr
<GradientStops
> aStops
,
347 const Matrix
& aMatrix
= Matrix())
350 mStops(std::move(aStops
)),
353 PatternType
GetType() const override
{ return PatternType::LINEAR_GRADIENT
; }
355 Pattern
* CloneWeak() const override
{
356 return new Weak(mBegin
, mEnd
, do_AddRef(mStops
), mMatrix
);
359 bool IsWeak() const override
{
360 return std::is_same
<decltype(*this), Weak
>::value
;
363 bool IsValid() const override
{ return IsRefValid(mStops
); }
365 template <template <typename
> typename T
>
366 bool operator==(const LinearGradientPatternT
<T
>& aOther
) const {
367 return mBegin
== aOther
.mBegin
&& mEnd
== aOther
.mEnd
&&
368 mStops
== aOther
.mStops
&& mMatrix
.ExactlyEquals(aOther
.mMatrix
);
371 bool operator==(const Pattern
& aOther
) const override
{
372 if (aOther
.GetType() != PatternType::LINEAR_GRADIENT
) {
375 return aOther
.IsWeak()
376 ? *this == static_cast<const Weak
&>(aOther
)
377 : *this == static_cast<const LinearGradientPatternT
<>&>(aOther
);
380 Point mBegin
; //!< Start of the linear gradient
381 Point mEnd
; /**< End of the linear gradient - NOTE: In the case
382 of a zero length gradient it will act as the
383 color of the last stop. */
384 REF
<GradientStops
> mStops
; /**< GradientStops object for this gradient, this
385 should match the backend type of the draw
386 target this pattern will be used with. */
387 Matrix mMatrix
; /**< A matrix that transforms the pattern into
391 typedef LinearGradientPatternT
<> LinearGradientPattern
;
394 * This class is used for Radial Gradient Patterns, the gradient stops are
395 * stored in a separate object and are backend dependent. This class itself
396 * may be used on the stack.
398 template <template <typename
> typename REF
= RefPtr
>
399 class RadialGradientPatternT
: public Pattern
{
400 typedef RadialGradientPatternT
<ThreadSafeWeakPtr
> Weak
;
403 /// For constructor parameter description, see member data documentation.
404 RadialGradientPatternT(const Point
& aCenter1
, const Point
& aCenter2
,
405 Float aRadius1
, Float aRadius2
,
406 RefPtr
<GradientStops
> aStops
,
407 const Matrix
& aMatrix
= Matrix())
408 : mCenter1(aCenter1
),
412 mStops(std::move(aStops
)),
415 PatternType
GetType() const override
{ return PatternType::RADIAL_GRADIENT
; }
417 Pattern
* CloneWeak() const override
{
418 return new Weak(mCenter1
, mCenter2
, mRadius1
, mRadius2
, do_AddRef(mStops
),
422 bool IsWeak() const override
{
423 return std::is_same
<decltype(*this), Weak
>::value
;
426 bool IsValid() const override
{ return IsRefValid(mStops
); }
428 template <template <typename
> typename T
>
429 bool operator==(const RadialGradientPatternT
<T
>& aOther
) const {
430 return mCenter1
== aOther
.mCenter1
&& mCenter2
== aOther
.mCenter2
&&
431 mRadius1
== aOther
.mRadius1
&& mRadius2
== aOther
.mRadius2
&&
432 mStops
== aOther
.mStops
&& mMatrix
.ExactlyEquals(aOther
.mMatrix
);
435 bool operator==(const Pattern
& aOther
) const override
{
436 if (aOther
.GetType() != PatternType::RADIAL_GRADIENT
) {
439 return aOther
.IsWeak()
440 ? *this == static_cast<const Weak
&>(aOther
)
441 : *this == static_cast<const RadialGradientPatternT
<>&>(aOther
);
444 Point mCenter1
; //!< Center of the inner (focal) circle.
445 Point mCenter2
; //!< Center of the outer circle.
446 Float mRadius1
; //!< Radius of the inner (focal) circle.
447 Float mRadius2
; //!< Radius of the outer circle.
448 REF
<GradientStops
> mStops
; /**< GradientStops object for this gradient, this
449 should match the backend type of the draw
450 target this pattern will be used with. */
451 Matrix mMatrix
; //!< A matrix that transforms the pattern into user space
454 typedef RadialGradientPatternT
<> RadialGradientPattern
;
457 * This class is used for Conic Gradient Patterns, the gradient stops are
458 * stored in a separate object and are backend dependent. This class itself
459 * may be used on the stack.
461 template <template <typename
> typename REF
= RefPtr
>
462 class ConicGradientPatternT
: public Pattern
{
463 typedef ConicGradientPatternT
<ThreadSafeWeakPtr
> Weak
;
466 /// For constructor parameter description, see member data documentation.
467 ConicGradientPatternT(const Point
& aCenter
, Float aAngle
, Float aStartOffset
,
468 Float aEndOffset
, RefPtr
<GradientStops
> aStops
,
469 const Matrix
& aMatrix
= Matrix())
472 mStartOffset(aStartOffset
),
473 mEndOffset(aEndOffset
),
474 mStops(std::move(aStops
)),
477 PatternType
GetType() const override
{ return PatternType::CONIC_GRADIENT
; }
479 Pattern
* CloneWeak() const override
{
480 return new Weak(mCenter
, mAngle
, mStartOffset
, mEndOffset
,
481 do_AddRef(mStops
), mMatrix
);
484 bool IsWeak() const override
{
485 return std::is_same
<decltype(*this), Weak
>::value
;
488 bool IsValid() const override
{ return IsRefValid(mStops
); }
490 template <template <typename
> typename T
>
491 bool operator==(const ConicGradientPatternT
<T
>& aOther
) const {
492 return mCenter
== aOther
.mCenter
&& mAngle
== aOther
.mAngle
&&
493 mStartOffset
== aOther
.mStartOffset
&&
494 mEndOffset
== aOther
.mEndOffset
&& mStops
== aOther
.mStops
&&
495 mMatrix
.ExactlyEquals(aOther
.mMatrix
);
498 bool operator==(const Pattern
& aOther
) const override
{
499 if (aOther
.GetType() != PatternType::CONIC_GRADIENT
) {
502 return aOther
.IsWeak()
503 ? *this == static_cast<const Weak
&>(aOther
)
504 : *this == static_cast<const ConicGradientPatternT
<>&>(aOther
);
507 Point mCenter
; //!< Center of the gradient
508 Float mAngle
; //!< Start angle of gradient
509 Float mStartOffset
; // Offset of first stop
510 Float mEndOffset
; // Offset of last stop
511 REF
<GradientStops
> mStops
; /**< GradientStops object for this gradient, this
512 should match the backend type of the draw
513 target this pattern will be used with. */
514 Matrix mMatrix
; //!< A matrix that transforms the pattern into user space
517 typedef ConicGradientPatternT
<> ConicGradientPattern
;
520 * This class is used for Surface Patterns, they wrap a surface and a
521 * repetition mode for the surface. This may be used on the stack.
523 template <template <typename
> typename REF
= RefPtr
>
524 class SurfacePatternT
: public Pattern
{
525 typedef SurfacePatternT
<ThreadSafeWeakPtr
> Weak
;
528 /// For constructor parameter description, see member data documentation.
529 SurfacePatternT(RefPtr
<SourceSurface
> aSourceSurface
, ExtendMode aExtendMode
,
530 const Matrix
& aMatrix
= Matrix(),
531 SamplingFilter aSamplingFilter
= SamplingFilter::GOOD
,
532 const IntRect
& aSamplingRect
= IntRect())
533 : mSurface(std::move(aSourceSurface
)),
534 mExtendMode(aExtendMode
),
535 mSamplingFilter(aSamplingFilter
),
537 mSamplingRect(aSamplingRect
) {}
539 PatternType
GetType() const override
{ return PatternType::SURFACE
; }
541 Pattern
* CloneWeak() const override
{
542 return new Weak(do_AddRef(mSurface
), mExtendMode
, mMatrix
, mSamplingFilter
,
546 bool IsWeak() const override
{
547 return std::is_same
<decltype(*this), Weak
>::value
;
550 bool IsValid() const override
{ return IsRefValid(mSurface
); }
552 template <template <typename
> typename T
>
553 bool operator==(const SurfacePatternT
<T
>& aOther
) const {
554 return mSurface
== aOther
.mSurface
&& mExtendMode
== aOther
.mExtendMode
&&
555 mSamplingFilter
== aOther
.mSamplingFilter
&&
556 mMatrix
.ExactlyEquals(aOther
.mMatrix
) &&
557 mSamplingRect
.IsEqualEdges(aOther
.mSamplingRect
);
560 bool operator==(const Pattern
& aOther
) const override
{
561 if (aOther
.GetType() != PatternType::SURFACE
) {
564 return aOther
.IsWeak()
565 ? *this == static_cast<const Weak
&>(aOther
)
566 : *this == static_cast<const SurfacePatternT
<>&>(aOther
);
569 REF
<SourceSurface
> mSurface
; //!< Surface to use for drawing
570 ExtendMode mExtendMode
; /**< This determines how the image is extended
571 outside the bounds of the image */
573 mSamplingFilter
; //!< Resampling filter for resampling the image.
574 Matrix mMatrix
; //!< Transforms the pattern into user space
576 IntRect mSamplingRect
; /**< Rect that must not be sampled outside of,
577 or an empty rect if none has been
581 typedef SurfacePatternT
<> SurfacePattern
;
585 static const int32_t kReasonableSurfaceSize
= 8192;
588 * This is the base class for source surfaces. These objects are surfaces
589 * which may be used as a source in a SurfacePattern or a DrawSurface call.
590 * They cannot be drawn to directly.
592 * Although SourceSurface has thread-safe refcount, some SourceSurface cannot
593 * be used on random threads at the same time. Only DataSourceSurface can be
594 * used on random threads now. This will be fixed in the future. Eventually
595 * all SourceSurface should be thread-safe.
597 class SourceSurface
: public SupportsThreadSafeWeakPtr
<SourceSurface
> {
599 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface
)
600 virtual ~SourceSurface() = default;
602 virtual SurfaceType
GetType() const = 0;
603 virtual IntSize
GetSize() const = 0;
604 /* GetRect is useful for when the underlying surface doesn't actually
605 * have a backing store starting at 0, 0. e.g. SourceSurfaceOffset */
606 virtual IntRect
GetRect() const { return IntRect(IntPoint(0, 0), GetSize()); }
607 virtual SurfaceFormat
GetFormat() const = 0;
610 * Structure containing memory size information for the surface.
621 void Accumulate(const SizeOfInfo
& aOther
) {
622 mHeapBytes
+= aOther
.mHeapBytes
;
623 mNonHeapBytes
+= aOther
.mNonHeapBytes
;
624 mUnknownBytes
+= aOther
.mUnknownBytes
;
625 mExternalHandles
+= aOther
.mExternalHandles
;
626 if (aOther
.mExternalId
) {
627 mExternalId
= aOther
.mExternalId
;
629 mTypes
|= aOther
.mTypes
;
632 void AddType(SurfaceType aType
) { mTypes
|= 1 << uint32_t(aType
); }
634 size_t mHeapBytes
; // Bytes allocated on the heap.
635 size_t mNonHeapBytes
; // Bytes allocated off the heap.
636 size_t mUnknownBytes
; // Bytes allocated to either, but unknown.
637 size_t mExternalHandles
; // Open handles for the surface.
638 uint64_t mExternalId
; // External ID for WebRender, if available.
639 uint32_t mTypes
; // Bit shifted values representing SurfaceType.
643 * Get the size information of the underlying data buffer.
645 virtual void SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
,
646 SizeOfInfo
& aInfo
) const {
647 // Default is to estimate the footprint based on its size/format.
648 auto size
= GetSize();
649 auto format
= GetFormat();
650 aInfo
.AddType(GetType());
651 aInfo
.mUnknownBytes
= size
.width
* size
.height
* BytesPerPixel(format
);
654 /** This returns false if some event has made this source surface invalid for
655 * usage with current DrawTargets. For example in the case of Direct2D this
656 * could return false if we have switched devices since this surface was
659 virtual bool IsValid() const { return true; }
662 * This returns true if it is the same underlying surface data, even if
663 * the objects are different (e.g. indirection due to
664 * DataSourceSurfaceWrapper).
666 virtual bool Equals(SourceSurface
* aOther
, bool aSymmetric
= true) {
667 return this == aOther
||
668 (aSymmetric
&& aOther
&& aOther
->Equals(this, false));
672 * This function will return true if the surface type matches that of a
673 * DataSourceSurface and if GetDataSurface will return the same object.
675 bool IsDataSourceSurface() const {
677 case SurfaceType::DATA
:
678 case SurfaceType::DATA_SHARED
:
679 case SurfaceType::DATA_RECYCLING_SHARED
:
680 case SurfaceType::DATA_ALIGNED
:
681 case SurfaceType::DATA_SHARED_WRAPPER
:
682 case SurfaceType::DATA_MAPPED
:
683 case SurfaceType::SKIA
:
684 case SurfaceType::WEBGL
:
692 * This function will get a DataSourceSurface for this surface, a
693 * DataSourceSurface's data can be accessed directly.
695 virtual already_AddRefed
<DataSourceSurface
> GetDataSurface() = 0;
697 /** This function will return a SourceSurface without any offset. */
698 virtual already_AddRefed
<SourceSurface
> GetUnderlyingSurface() {
699 RefPtr
<SourceSurface
> surface
= this;
700 return surface
.forget();
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.
706 virtual void* GetNativeSurface(NativeSurfaceType aType
) { return nullptr; }
708 void AddUserData(UserDataKey
* key
, void* userData
, void (*destroy
)(void*)) {
709 mUserData
.Add(key
, userData
, destroy
);
711 void* GetUserData(UserDataKey
* key
) const { return mUserData
.Get(key
); }
712 void RemoveUserData(UserDataKey
* key
) { mUserData
.RemoveAndDestroy(key
); }
714 /** Tries to extract an optimal subrect for the surface. This may fail if the
715 * request can't be satisfied.
717 virtual already_AddRefed
<SourceSurface
> ExtractSubrect(const IntRect
& aRect
) {
722 friend class StoredPattern
;
724 ThreadSafeUserData mUserData
;
727 class DataSourceSurface
: public SourceSurface
{
729 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurface
, override
)
730 DataSourceSurface() : mMapCount(0) {}
733 virtual ~DataSourceSurface() { MOZ_ASSERT(mMapCount
== 0); }
736 struct MappedSurface
{
737 uint8_t* mData
= nullptr;
741 enum MapType
{ READ
, WRITE
, READ_WRITE
};
744 * This is a scoped version of Map(). Map() is called in the constructor and
745 * Unmap() in the destructor. Use this for automatic unmapping of your data
748 * Use IsMapped() to verify whether Map() succeeded or not.
750 class ScopedMap final
{
752 ScopedMap(DataSourceSurface
* aSurface
, MapType aType
)
753 : mSurface(aSurface
), mIsMapped(aSurface
->Map(aType
, &mMap
)) {}
755 ScopedMap(ScopedMap
&& aOther
)
756 : mSurface(std::move(aOther
.mSurface
)),
758 mIsMapped(aOther
.mIsMapped
) {
759 aOther
.mMap
.mData
= nullptr;
760 aOther
.mIsMapped
= false;
763 ScopedMap
& operator=(ScopedMap
&& aOther
) {
767 mSurface
= std::move(aOther
.mSurface
);
769 mIsMapped
= aOther
.mIsMapped
;
770 aOther
.mMap
.mData
= nullptr;
771 aOther
.mIsMapped
= false;
781 uint8_t* GetData() const {
782 MOZ_ASSERT(mIsMapped
);
786 int32_t GetStride() const {
787 MOZ_ASSERT(mIsMapped
);
791 const MappedSurface
* GetMappedSurface() const {
792 MOZ_ASSERT(mIsMapped
);
796 const DataSourceSurface
* GetSurface() const {
797 MOZ_ASSERT(mIsMapped
);
801 bool IsMapped() const { return mIsMapped
; }
804 ScopedMap(const ScopedMap
& aOther
) = delete;
805 ScopedMap
& operator=(const ScopedMap
& aOther
) = delete;
807 RefPtr
<DataSourceSurface
> mSurface
;
812 SurfaceType
GetType() const override
{ return SurfaceType::DATA
; }
814 * Get the raw bitmap data of the surface.
815 * Can return null if there was OOM allocating surface data.
817 * Deprecated means you shouldn't be using this!! Use Map instead.
818 * Please deny any reviews which add calls to this!
820 virtual uint8_t* GetData() = 0;
823 * Stride of the surface, distance in bytes between the start of the image
824 * data belonging to row y and row y+1. This may be negative.
825 * Can return 0 if there was OOM allocating surface data.
827 virtual int32_t Stride() = 0;
830 * The caller is responsible for ensuring aMappedSurface is not null.
831 // Althought Map (and Moz2D in general) isn't normally threadsafe,
832 // we want to allow it for SourceSurfaceRawData since it should
833 // always be fine (for reading at least).
835 // This is the same as the base class implementation except using
836 // mMapCount instead of mIsMapped since that breaks for multithread.
838 // Once mfbt supports Monitors we should implement proper read/write
839 // locking to prevent write races.
841 virtual bool Map(MapType
, MappedSurface
* aMappedSurface
) {
842 aMappedSurface
->mData
= GetData();
843 aMappedSurface
->mStride
= Stride();
844 bool success
= !!aMappedSurface
->mData
;
851 virtual void Unmap() {
853 MOZ_ASSERT(mMapCount
>= 0);
857 * Returns a DataSourceSurface with the same data as this one, but
858 * guaranteed to have surface->GetType() == SurfaceType::DATA.
860 * The returning surface might be null, because of OOM or gfx device reset.
861 * The caller needs to do null-check before using it.
863 already_AddRefed
<DataSourceSurface
> GetDataSurface() override
;
866 * Returns whether or not the data was allocated on the heap. This should
867 * be used to determine if the memory needs to be cleared to 0.
869 virtual bool OnHeap() const { return true; }
872 * Yields a dirty rect of what has changed since it was last called.
874 virtual Maybe
<IntRect
> TakeDirtyRect() { return Nothing(); }
877 * Indicate a region which has changed in the surface.
879 virtual void Invalidate(const IntRect
& aDirtyRect
) {}
882 Atomic
<int32_t> mMapCount
;
885 /** This is an abstract object that accepts path segments. */
886 class PathSink
: public RefCounted
<PathSink
> {
888 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathSink
)
889 virtual ~PathSink() = default;
891 /** Move the current point in the path, any figure currently being drawn will
892 * be considered closed during fill operations, however when stroking the
893 * closing line segment will not be drawn.
895 virtual void MoveTo(const Point
& aPoint
) = 0;
896 /** Add a linesegment to the current figure */
897 virtual void LineTo(const Point
& aPoint
) = 0;
898 /** Add a cubic bezier curve to the current figure */
899 virtual void BezierTo(const Point
& aCP1
, const Point
& aCP2
,
900 const Point
& aCP3
) = 0;
901 /** Add a quadratic bezier curve to the current figure */
902 virtual void QuadraticBezierTo(const Point
& aCP1
, const Point
& aCP2
) = 0;
903 /** Close the current figure, this will essentially generate a line segment
904 * from the current point to the starting point for the current figure
906 virtual void Close() = 0;
907 /** Add an arc to the current figure */
908 virtual void Arc(const Point
& aOrigin
, float aRadius
, float aStartAngle
,
909 float aEndAngle
, bool aAntiClockwise
= false) = 0;
911 virtual Point
CurrentPoint() const { return mCurrentPoint
; }
913 virtual Point
BeginPoint() const { return mBeginPoint
; }
915 virtual void SetCurrentPoint(const Point
& aPoint
) { mCurrentPoint
= aPoint
; }
917 virtual void SetBeginPoint(const Point
& aPoint
) { mBeginPoint
= aPoint
; }
920 /** Point the current subpath is at - or where the next subpath will start
921 * if there is no active subpath.
925 /** Position of the previous MoveTo operation. */
932 /** The path class is used to create (sets of) figures of any shape that can be
933 * filled or stroked to a DrawTarget
935 class Path
: public external::AtomicRefCounted
<Path
> {
937 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(Path
)
940 virtual BackendType
GetBackendType() const = 0;
942 /** This returns a PathBuilder object that contains a copy of the contents of
943 * this path and is still writable.
945 inline already_AddRefed
<PathBuilder
> CopyToBuilder() const {
946 return CopyToBuilder(GetFillRule());
948 inline already_AddRefed
<PathBuilder
> TransformedCopyToBuilder(
949 const Matrix
& aTransform
) const {
950 return TransformedCopyToBuilder(aTransform
, GetFillRule());
952 /** This returns a PathBuilder object that contains a copy of the contents of
953 * this path, converted to use the specified FillRule, and still writable.
955 virtual already_AddRefed
<PathBuilder
> CopyToBuilder(
956 FillRule aFillRule
) const = 0;
957 virtual already_AddRefed
<PathBuilder
> TransformedCopyToBuilder(
958 const Matrix
& aTransform
, FillRule aFillRule
) const = 0;
960 /** This function checks if a point lies within a path. It allows passing a
961 * transform that will transform the path to the coordinate space in which
964 virtual bool ContainsPoint(const Point
& aPoint
,
965 const Matrix
& aTransform
) const = 0;
967 /** This function checks if a point lies within the stroke of a path using the
968 * specified strokeoptions. It allows passing a transform that will transform
969 * the path to the coordinate space in which aPoint is given.
971 virtual bool StrokeContainsPoint(const StrokeOptions
& aStrokeOptions
,
973 const Matrix
& aTransform
) const = 0;
975 /** This functions gets the bounds of this path. These bounds are not
976 * guaranteed to be tight. A transform may be specified that gives the bounds
977 * after application of the transform.
979 virtual Rect
GetBounds(const Matrix
& aTransform
= Matrix()) const = 0;
981 /** This function gets the bounds of the stroke of this path using the
982 * specified strokeoptions. These bounds are not guaranteed to be tight.
983 * A transform may be specified that gives the bounds after application of
986 virtual Rect
GetStrokedBounds(const StrokeOptions
& aStrokeOptions
,
987 const Matrix
& aTransform
= Matrix()) const = 0;
989 /** Gets conservative bounds for the path, optionally stroked or transformed.
990 * This function will prioritize speed of computation over tightness of the
991 * computed bounds if the backend supports the distinction.
993 virtual Rect
GetFastBounds(
994 const Matrix
& aTransform
= Matrix(),
995 const StrokeOptions
* aStrokeOptions
= nullptr) const;
997 /** Take the contents of this path and stream it to another sink, this works
998 * regardless of the backend that might be used for the destination sink.
1000 virtual void StreamToSink(PathSink
* aSink
) const = 0;
1002 /** This gets the fillrule this path's builder was created with. This is not
1005 virtual FillRule
GetFillRule() const = 0;
1007 virtual Float
ComputeLength();
1009 virtual Maybe
<Rect
> AsRect() const { return Nothing(); }
1011 virtual Point
ComputePointAtLength(Float aLength
, Point
* aTangent
= nullptr);
1013 virtual bool IsEmpty() const = 0;
1017 void EnsureFlattenedPath();
1019 RefPtr
<FlattenedPath
> mFlattenedPath
;
1022 /** The PathBuilder class allows path creation. Once finish is called on the
1023 * pathbuilder it may no longer be written to.
1025 class PathBuilder
: public PathSink
{
1027 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilder
, override
)
1028 /** Finish writing to the path and return a Path object that can be used for
1029 * drawing. Future use of the builder results in a crash!
1031 virtual already_AddRefed
<Path
> Finish() = 0;
1033 virtual BackendType
GetBackendType() const = 0;
1035 virtual bool IsActive() const = 0;
1043 static inline bool operator==(const Glyph
& aOne
, const Glyph
& aOther
) {
1044 return aOne
.mIndex
== aOther
.mIndex
&& aOne
.mPosition
== aOther
.mPosition
;
1047 /** This class functions as a glyph buffer that can be drawn to a DrawTarget.
1048 * @todo XXX - This should probably contain the guts of gfxTextRun in the future
1049 * as roc suggested. But for now it's a simple container for a glyph vector.
1051 struct GlyphBuffer
{
1053 mGlyphs
; //!< A pointer to a buffer of glyphs. Managed by the caller.
1054 uint32_t mNumGlyphs
; //!< Number of glyphs mGlyphs points to.
1057 #ifdef MOZ_ENABLE_FREETYPE
1060 /** SharedFTFaceData abstracts data that may be used to back a SharedFTFace.
1061 * Its main function is to manage the lifetime of the data and ensure that it
1062 * lasts as long as the face.
1064 class SharedFTFaceData
{
1066 /** Utility for creating a new face from this data. */
1067 virtual already_AddRefed
<SharedFTFace
> CloneFace(int aFaceIndex
= 0) {
1070 /** Binds the data's lifetime to the face. */
1071 virtual void BindData() = 0;
1072 /** Signals that the data is no longer needed by a face. */
1073 virtual void ReleaseData() = 0;
1076 /** Wrapper class for ref-counted SharedFTFaceData that handles calling the
1077 * appropriate ref-counting methods
1080 class SharedFTFaceRefCountedData
: public SharedFTFaceData
{
1082 void BindData() { static_cast<T
*>(this)->AddRef(); }
1083 void ReleaseData() { static_cast<T
*>(this)->Release(); }
1086 // Helper class used for clearing out user font data when FT font
1087 // face is destroyed. Since multiple faces may use the same data, be
1088 // careful to assure that the data is only cleared out when all uses
1089 // expire. The font entry object contains a refptr to FTUserFontData and
1090 // each FT face created from that font entry contains a refptr to that
1091 // same FTUserFontData object.
1092 // This is also attached to FT faces for installed fonts (recording the
1093 // filename, rather than storing the font data) if variations are present.
1094 class FTUserFontData final
1095 : public mozilla::gfx::SharedFTFaceRefCountedData
<FTUserFontData
> {
1097 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FTUserFontData
)
1099 FTUserFontData(const uint8_t* aData
, uint32_t aLength
)
1100 : mFontData(aData
), mLength(aLength
) {}
1101 explicit FTUserFontData(const char* aFilename
) : mFilename(aFilename
) {}
1103 const uint8_t* FontData() const { return mFontData
; }
1105 already_AddRefed
<mozilla::gfx::SharedFTFace
> CloneFace(
1106 int aFaceIndex
= 0) override
;
1111 free((void*)mFontData
);
1115 std::string mFilename
;
1116 const uint8_t* mFontData
= nullptr;
1117 uint32_t mLength
= 0;
1120 /** SharedFTFace is a shared wrapper around an FT_Face. It is ref-counted,
1121 * unlike FT_Face itself, so that it may be shared among many users with
1122 * RefPtr. Users should take care to lock SharedFTFace before accessing any
1123 * FT_Face fields that may change to ensure exclusive access to it. It also
1124 * allows backing data's lifetime to be bound to it via SharedFTFaceData so
1125 * that the data will not disappear before the face does.
1127 class SharedFTFace
: public external::AtomicRefCounted
<SharedFTFace
> {
1129 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SharedFTFace
)
1131 explicit SharedFTFace(FT_Face aFace
, SharedFTFaceData
* aData
);
1132 virtual ~SharedFTFace();
1134 FT_Face
GetFace() const { return mFace
; }
1135 SharedFTFaceData
* GetData() const { return mData
; }
1137 /** Locks the face for exclusive access by a given owner. Returns false if
1138 * the given owner is acquiring the lock for the first time, and true if
1139 * the owner was the prior owner of the lock. Thus the return value can be
1140 * used to do owner-specific initialization of the FT face such as setting
1141 * a size or transform that may have been invalidated by a previous owner.
1142 * If no owner is given, then the user should avoid modifying any state on
1143 * the face so as not to invalidate the prior owner's modification.
1145 bool Lock(const void* aOwner
= nullptr) MOZ_CAPABILITY_ACQUIRE(mLock
) {
1147 return !aOwner
|| mLastLockOwner
.exchange(aOwner
) == aOwner
;
1149 void Unlock() MOZ_CAPABILITY_RELEASE(mLock
) { mLock
.Unlock(); }
1151 /** Should be called when a lock owner is destroyed so that we don't have
1152 * a dangling pointer to a destroyed owner.
1154 void ForgetLockOwner(const void* aOwner
) {
1156 mLastLockOwner
.compareExchange(aOwner
, nullptr);
1162 SharedFTFaceData
* mData
;
1164 // Remember the last owner of the lock, even after unlocking, to allow users
1165 // to avoid reinitializing state on the FT face if the last owner hasn't
1166 // changed by the next time it is locked with the same owner.
1167 Atomic
<const void*> mLastLockOwner
;
1171 class UnscaledFont
: public SupportsThreadSafeWeakPtr
<UnscaledFont
> {
1173 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFont
)
1175 virtual ~UnscaledFont();
1177 virtual FontType
GetType() const = 0;
1179 static uint32_t DeletionCounter() { return sDeletionCounter
; }
1181 typedef void (*FontFileDataOutput
)(const uint8_t* aData
, uint32_t aLength
,
1182 uint32_t aIndex
, void* aBaton
);
1183 typedef void (*FontInstanceDataOutput
)(const uint8_t* aData
, uint32_t aLength
,
1185 typedef void (*FontDescriptorOutput
)(const uint8_t* aData
, uint32_t aLength
,
1186 uint32_t aIndex
, void* aBaton
);
1188 virtual bool GetFontFileData(FontFileDataOutput
, void*) { return false; }
1190 virtual bool GetFontInstanceData(FontInstanceDataOutput
, void*) {
1194 virtual bool GetFontDescriptor(FontDescriptorOutput
, void*) { return false; }
1196 virtual already_AddRefed
<ScaledFont
> CreateScaledFont(
1197 Float aGlyphSize
, const uint8_t* aInstanceData
,
1198 uint32_t aInstanceDataLength
, const FontVariation
* aVariations
,
1199 uint32_t aNumVariations
) {
1203 virtual already_AddRefed
<ScaledFont
> CreateScaledFontFromWRFont(
1204 Float aGlyphSize
, const wr::FontInstanceOptions
* aOptions
,
1205 const wr::FontInstancePlatformOptions
* aPlatformOptions
,
1206 const FontVariation
* aVariations
, uint32_t aNumVariations
) {
1207 return CreateScaledFont(aGlyphSize
, nullptr, 0, aVariations
,
1212 UnscaledFont() = default;
1215 static Atomic
<uint32_t> sDeletionCounter
;
1218 /** This class is an abstraction of a backend/platform specific font object
1219 * at a particular size. It is passed into text drawing calls to describe
1220 * the font used for the drawing call.
1222 class ScaledFont
: public SupportsThreadSafeWeakPtr
<ScaledFont
> {
1224 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont
)
1226 virtual ~ScaledFont();
1228 virtual FontType
GetType() const = 0;
1229 virtual Float
GetSize() const = 0;
1230 virtual AntialiasMode
GetDefaultAAMode() { return AntialiasMode::DEFAULT
; }
1232 static uint32_t DeletionCounter() { return sDeletionCounter
; }
1234 /** This allows getting a path that describes the outline of a set of glyphs.
1235 * A target is passed in so that the guarantee is made the returned path
1236 * can be used with any DrawTarget that has the same backend as the one
1239 virtual already_AddRefed
<Path
> GetPathForGlyphs(
1240 const GlyphBuffer
& aBuffer
, const DrawTarget
* aTarget
) = 0;
1242 /** This copies the path describing the glyphs into a PathBuilder. We use this
1243 * API rather than a generic API to append paths because it allows easier
1244 * implementation in some backends, and more efficient implementation in
1247 virtual void CopyGlyphsToBuilder(const GlyphBuffer
& aBuffer
,
1248 PathBuilder
* aBuilder
,
1249 const Matrix
* aTransformHint
= nullptr) = 0;
1251 typedef void (*FontInstanceDataOutput
)(const uint8_t* aData
, uint32_t aLength
,
1252 const FontVariation
* aVariations
,
1253 uint32_t aNumVariations
, void* aBaton
);
1255 virtual bool GetFontInstanceData(FontInstanceDataOutput
, void*) {
1259 virtual bool GetWRFontInstanceOptions(
1260 Maybe
<wr::FontInstanceOptions
>* aOutOptions
,
1261 Maybe
<wr::FontInstancePlatformOptions
>* aOutPlatformOptions
,
1262 std::vector
<FontVariation
>* aOutVariations
) {
1266 virtual bool CanSerialize() { return false; }
1268 virtual bool HasVariationSettings() { return false; }
1270 virtual bool MayUseBitmaps() { return false; }
1272 virtual bool UseSubpixelPosition() const { return false; }
1274 void AddUserData(UserDataKey
* key
, void* userData
, void (*destroy
)(void*)) {
1275 mUserData
.Add(key
, userData
, destroy
);
1277 void* GetUserData(UserDataKey
* key
) { return mUserData
.Get(key
); }
1279 void RemoveUserData(UserDataKey
* key
) { mUserData
.RemoveAndDestroy(key
); }
1281 const RefPtr
<UnscaledFont
>& GetUnscaledFont() const { return mUnscaledFont
; }
1283 virtual cairo_scaled_font_t
* GetCairoScaledFont() { return nullptr; }
1285 Float
GetSyntheticObliqueAngle() const { return mSyntheticObliqueAngle
; }
1286 void SetSyntheticObliqueAngle(Float aAngle
) {
1287 mSyntheticObliqueAngle
= aAngle
;
1291 explicit ScaledFont(const RefPtr
<UnscaledFont
>& aUnscaledFont
)
1292 : mUnscaledFont(aUnscaledFont
), mSyntheticObliqueAngle(0.0f
) {}
1294 ThreadSafeUserData mUserData
;
1295 RefPtr
<UnscaledFont
> mUnscaledFont
;
1296 Float mSyntheticObliqueAngle
;
1299 static Atomic
<uint32_t> sDeletionCounter
;
1303 * Derived classes hold a native font resource from which to create
1306 class NativeFontResource
1307 : public external::AtomicRefCounted
<NativeFontResource
> {
1309 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResource
)
1312 * Creates a UnscaledFont using the font corresponding to the index.
1314 * @param aIndex index for the font within the resource.
1315 * @param aInstanceData pointer to read-only buffer of any available instance
1317 * @param aInstanceDataLength the size of the instance data.
1318 * @return an already_addrefed UnscaledFont, containing nullptr if failed.
1320 virtual already_AddRefed
<UnscaledFont
> CreateUnscaledFont(
1321 uint32_t aIndex
, const uint8_t* aInstanceData
,
1322 uint32_t aInstanceDataLength
) = 0;
1324 NativeFontResource(size_t aDataLength
);
1325 virtual ~NativeFontResource();
1327 static void RegisterMemoryReporter();
1333 /** This is the main class used for all the drawing. It is created through the
1334 * factory and accepts drawing commands. The results of drawing to a target
1335 * may be used either through a Snapshot or by flushing the target and directly
1336 * accessing the backing store a DrawTarget was created with.
1338 class DrawTarget
: public external::AtomicRefCounted
<DrawTarget
> {
1340 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget
)
1342 : mTransformDirty(false),
1343 mPermitSubpixelAA(false),
1344 mFormat(SurfaceFormat::UNKNOWN
) {}
1345 virtual ~DrawTarget() = default;
1347 virtual bool IsValid() const { return true; };
1348 virtual DrawTargetType
GetType() const = 0;
1350 virtual BackendType
GetBackendType() const = 0;
1352 virtual bool IsRecording() const { return false; }
1355 * Method to generate hyperlink in PDF output (with appropriate backend).
1357 virtual void Link(const char* aDestination
, const Rect
& aRect
) {}
1358 virtual void Destination(const char* aDestination
, const Point
& aPoint
) {}
1361 * Returns a SourceSurface which is a snapshot of the current contents of the
1362 * DrawTarget. Multiple calls to Snapshot() without any drawing operations in
1363 * between will normally return the same SourceSurface object.
1365 virtual already_AddRefed
<SourceSurface
> Snapshot() = 0;
1368 * Returns a SourceSurface which wraps the buffer backing the DrawTarget. The
1369 * contents of the buffer may change if there are drawing operations after
1370 * calling but only guarantees that it reflects the state at the time it was
1373 virtual already_AddRefed
<SourceSurface
> GetBackingSurface() {
1377 // Snapshots the contents and returns an alpha mask
1378 // based on the RGB values.
1379 virtual already_AddRefed
<SourceSurface
> IntoLuminanceSource(
1380 LuminanceType aLuminanceType
, float aOpacity
);
1381 virtual IntSize
GetSize() const = 0;
1382 virtual IntRect
GetRect() const { return IntRect(IntPoint(0, 0), GetSize()); }
1385 * If possible returns the bits to this DrawTarget for direct manipulation.
1386 * While the bits is locked any modifications to this DrawTarget is forbidden.
1387 * Release takes the original data pointer for safety.
1389 virtual bool LockBits(uint8_t** aData
, IntSize
* aSize
, int32_t* aStride
,
1390 SurfaceFormat
* aFormat
, IntPoint
* aOrigin
= nullptr) {
1393 virtual void ReleaseBits(uint8_t* aData
) {}
1395 /** Ensure that the DrawTarget backend has flushed all drawing operations to
1396 * this draw target. This must be called before using the backing surface of
1397 * this draw target outside of GFX 2D code.
1399 virtual void Flush() = 0;
1402 * Draw a surface to the draw target. Possibly doing partial drawing or
1403 * applying scaling. No sampling happens outside the source.
1405 * @param aSurface Source surface to draw
1406 * @param aDest Destination rectangle that this drawing operation should draw
1408 * @param aSource Source rectangle in aSurface coordinates, this area of
1410 * will be stretched to the size of aDest.
1411 * @param aOptions General draw options that are applied to the operation
1412 * @param aSurfOptions DrawSurface options that are applied
1414 virtual void DrawSurface(
1415 SourceSurface
* aSurface
, const Rect
& aDest
, const Rect
& aSource
,
1416 const DrawSurfaceOptions
& aSurfOptions
= DrawSurfaceOptions(),
1417 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1420 * Draw a surface to the draw target, when the surface will be available
1421 * at a later time. This is only valid for recording DrawTargets.
1423 * This is considered fallible, and replaying this without making the surface
1424 * available to the replay will just skip the draw.
1426 virtual void DrawDependentSurface(uint64_t aId
, const Rect
& aDest
) {
1427 MOZ_CRASH("GFX: DrawDependentSurface");
1431 * Draw the output of a FilterNode to the DrawTarget.
1433 * @param aNode FilterNode to draw
1434 * @param aSourceRect Source rectangle in FilterNode space to draw
1435 * @param aDestPoint Destination point on the DrawTarget to draw the
1436 * SourceRectangle of the filter output to
1438 virtual void DrawFilter(FilterNode
* aNode
, const Rect
& aSourceRect
,
1439 const Point
& aDestPoint
,
1440 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1443 * Blend a surface to the draw target with a shadow. The shadow is drawn as a
1444 * gaussian blur using a specified sigma. The shadow is clipped to the size
1445 * of the input surface, so the input surface should contain a transparent
1446 * border the size of the approximate coverage of the blur (3 * aSigma).
1447 * NOTE: This function works in device space!
1449 * @param aSurface Source surface to draw.
1450 * @param aDest Destination point that this drawing operation should draw to.
1451 * @param aShadow Description of shadow to be drawn.
1452 * @param aOperator Composition operator used
1454 virtual void DrawSurfaceWithShadow(SourceSurface
* aSurface
,
1456 const ShadowOptions
& aShadow
,
1457 CompositionOp aOperator
) = 0;
1460 * Draws a shadow for the specified path, which may be optionally stroked.
1462 * @param aPath The path to use for the shadow geometry.
1463 * @param aPattern The pattern to use for filling the path.
1464 * @param aShadow Description of shadow to be drawn.
1465 * @param aOptions General drawing options to apply to drawing the path.
1466 * @param aStrokeOptions Stroking parameters that control stroking of path
1467 * geometry, if supplied.
1469 virtual void DrawShadow(const Path
* aPath
, const Pattern
& aPattern
,
1470 const ShadowOptions
& aShadow
,
1471 const DrawOptions
& aOptions
= DrawOptions(),
1472 const StrokeOptions
* aStrokeOptions
= nullptr);
1475 * Clear a rectangle on the draw target to transparent black. This will
1476 * respect the clipping region and transform.
1478 * @param aRect Rectangle to clear
1480 virtual void ClearRect(const Rect
& aRect
) = 0;
1483 * This is essentially a 'memcpy' between two surfaces. It moves a pixel
1484 * aligned area from the source surface unscaled directly onto the
1485 * drawtarget. This ignores both transform and clip.
1487 * @param aSurface Surface to copy from
1488 * @param aSourceRect Source rectangle to be copied
1489 * @param aDest Destination point to copy the surface to
1491 virtual void CopySurface(SourceSurface
* aSurface
, const IntRect
& aSourceRect
,
1492 const IntPoint
& aDestination
) = 0;
1494 /** @see CopySurface
1495 * Same as CopySurface, except uses itself as the source.
1497 * Some backends may be able to optimize this better
1498 * than just taking a snapshot and using CopySurface.
1500 virtual void CopyRect(const IntRect
& aSourceRect
,
1501 const IntPoint
& aDestination
) {
1502 RefPtr
<SourceSurface
> source
= Snapshot();
1503 CopySurface(source
, aSourceRect
, aDestination
);
1507 * Fill a rectangle on the DrawTarget with a certain source pattern.
1509 * @param aRect Rectangle that forms the mask of this filling operation
1510 * @param aPattern Pattern that forms the source of this filling operation
1511 * @param aOptions Options that are applied to this operation
1513 virtual void FillRect(const Rect
& aRect
, const Pattern
& aPattern
,
1514 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1517 * Fill a rounded rectangle on the DrawTarget with a certain source pattern.
1519 * @param aRect Rounded rectangle that forms the mask of this filling
1521 * @param aPattern Pattern that forms the source of this filling operation
1522 * @param aOptions Options that are applied to this operation
1524 virtual void FillRoundedRect(const RoundedRect
& aRect
,
1525 const Pattern
& aPattern
,
1526 const DrawOptions
& aOptions
= DrawOptions());
1529 * Stroke a rectangle on the DrawTarget with a certain source pattern.
1531 * @param aRect Rectangle that forms the mask of this stroking operation
1532 * @param aPattern Pattern that forms the source of this stroking operation
1533 * @param aOptions Options that are applied to this operation
1535 virtual void StrokeRect(const Rect
& aRect
, const Pattern
& aPattern
,
1536 const StrokeOptions
& aStrokeOptions
= StrokeOptions(),
1537 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1540 * Stroke a line on the DrawTarget with a certain source pattern.
1542 * @param aStart Starting point of the line
1543 * @param aEnd End point of the line
1544 * @param aPattern Pattern that forms the source of this stroking operation
1545 * @param aOptions Options that are applied to this operation
1547 virtual void StrokeLine(const Point
& aStart
, const Point
& aEnd
,
1548 const Pattern
& aPattern
,
1549 const StrokeOptions
& aStrokeOptions
= StrokeOptions(),
1550 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1553 * Stroke a circle on the DrawTarget with a certain source pattern.
1555 * @param aCircle the parameters of the circle
1556 * @param aPattern Pattern that forms the source of this stroking operation
1557 * @param aOptions Options that are applied to this operation
1559 virtual void StrokeCircle(
1560 const Point
& aOrigin
, float radius
, const Pattern
& aPattern
,
1561 const StrokeOptions
& aStrokeOptions
= StrokeOptions(),
1562 const DrawOptions
& aOptions
= DrawOptions());
1565 * Stroke a path on the draw target with a certain source pattern.
1567 * @param aPath Path that is to be stroked
1568 * @param aPattern Pattern that should be used for the stroke
1569 * @param aStrokeOptions Stroke options used for this operation
1570 * @param aOptions Draw options used for this operation
1572 virtual void Stroke(const Path
* aPath
, const Pattern
& aPattern
,
1573 const StrokeOptions
& aStrokeOptions
= StrokeOptions(),
1574 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1577 * Fill a path on the draw target with a certain source pattern.
1579 * @param aPath Path that is to be filled
1580 * @param aPattern Pattern that should be used for the fill
1581 * @param aOptions Draw options used for this operation
1583 virtual void Fill(const Path
* aPath
, const Pattern
& aPattern
,
1584 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1587 * Fill a circle on the DrawTarget with a certain source pattern.
1589 * @param aCircle the parameters of the circle
1590 * @param aPattern Pattern that forms the source of this stroking operation
1591 * @param aOptions Options that are applied to this operation
1593 virtual void FillCircle(const Point
& aOrigin
, float radius
,
1594 const Pattern
& aPattern
,
1595 const DrawOptions
& aOptions
= DrawOptions());
1598 * Fill a series of glyphs on the draw target with a certain source pattern.
1600 virtual void FillGlyphs(ScaledFont
* aFont
, const GlyphBuffer
& aBuffer
,
1601 const Pattern
& aPattern
,
1602 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1605 * Stroke a series of glyphs on the draw target with a certain source pattern.
1607 virtual void StrokeGlyphs(
1608 ScaledFont
* aFont
, const GlyphBuffer
& aBuffer
, const Pattern
& aPattern
,
1609 const StrokeOptions
& aStrokeOptions
= StrokeOptions(),
1610 const DrawOptions
& aOptions
= DrawOptions());
1613 * This takes a source pattern and a mask, and composites the source pattern
1614 * onto the destination surface using the alpha channel of the mask pattern
1615 * as a mask for the operation.
1617 * @param aSource Source pattern
1618 * @param aMask Mask pattern
1619 * @param aOptions Drawing options
1621 virtual void Mask(const Pattern
& aSource
, const Pattern
& aMask
,
1622 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1625 * This takes a source pattern and a mask, and composites the source pattern
1626 * onto the destination surface using the alpha channel of the mask source.
1627 * The operation is bound by the extents of the mask.
1629 * @param aSource Source pattern
1630 * @param aMask Mask surface
1631 * @param aOffset a transformed offset that the surface is masked at
1632 * @param aOptions Drawing options
1634 virtual void MaskSurface(const Pattern
& aSource
, SourceSurface
* aMask
,
1636 const DrawOptions
& aOptions
= DrawOptions()) = 0;
1639 * Draw aSurface using the 3D transform aMatrix. The DrawTarget's transform
1640 * and clip are applied after the 3D transform.
1642 * If the transform fails (i.e. because aMatrix is singular), false is
1643 * returned and nothing is drawn.
1645 virtual bool Draw3DTransformedSurface(SourceSurface
* aSurface
,
1646 const Matrix4x4
& aMatrix
);
1649 * Push a clip to the DrawTarget.
1651 * @param aPath The path to clip to
1653 virtual void PushClip(const Path
* aPath
) = 0;
1656 * Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
1657 * is specified in user space.
1659 * @param aRect The rect to clip to
1661 virtual void PushClipRect(const Rect
& aRect
) = 0;
1664 * Push a clip region specifed by the union of axis-aligned rectangular
1665 * clips to the DrawTarget. These rectangles are specified in device space.
1666 * This must be balanced by a corresponding call to PopClip within a layer.
1668 * @param aRects The rects to clip to
1669 * @param aCount The number of rectangles
1671 virtual void PushDeviceSpaceClipRects(const IntRect
* aRects
, uint32_t aCount
);
1673 /** Pop a clip from the DrawTarget. A pop without a corresponding push will
1676 virtual void PopClip() = 0;
1679 * Push a 'layer' to the DrawTarget, a layer is a temporary surface that all
1680 * drawing will be redirected to, this is used for example to support group
1681 * opacity or the masking of groups. Clips must be balanced within a layer,
1682 * i.e. between a matching PushLayer/PopLayer pair there must be as many
1683 * PushClip(Rect) calls as there are PopClip calls.
1685 * @param aOpaque Whether the layer will be opaque
1686 * @param aOpacity Opacity of the layer
1687 * @param aMask Mask applied to the layer
1688 * @param aMaskTransform Transform applied to the layer mask
1689 * @param aBounds Optional bounds in device space to which the layer is
1691 * @param aCopyBackground Whether to copy the background into the layer, this
1692 * is only supported when aOpaque is true.
1694 virtual void PushLayer(bool aOpaque
, Float aOpacity
, SourceSurface
* aMask
,
1695 const Matrix
& aMaskTransform
,
1696 const IntRect
& aBounds
= IntRect(),
1697 bool aCopyBackground
= false) {
1698 MOZ_CRASH("GFX: PushLayer");
1702 * Push a 'layer' to the DrawTarget, a layer is a temporary surface that all
1703 * drawing will be redirected to, this is used for example to support group
1704 * opacity or the masking of groups. Clips must be balanced within a layer,
1705 * i.e. between a matching PushLayer/PopLayer pair there must be as many
1706 * PushClip(Rect) calls as there are PopClip calls.
1708 * @param aOpaque Whether the layer will be opaque
1709 * @param aOpacity Opacity of the layer
1710 * @param aMask Mask applied to the layer
1711 * @param aMaskTransform Transform applied to the layer mask
1712 * @param aBounds Optional bounds in device space to which the layer is
1714 * @param aCopyBackground Whether to copy the background into the layer, this
1715 * is only supported when aOpaque is true.
1717 virtual void PushLayerWithBlend(bool aOpaque
, Float aOpacity
,
1718 SourceSurface
* aMask
,
1719 const Matrix
& aMaskTransform
,
1720 const IntRect
& aBounds
= IntRect(),
1721 bool aCopyBackground
= false,
1722 CompositionOp
= CompositionOp::OP_OVER
) {
1723 MOZ_CRASH("GFX: PushLayerWithBlend");
1727 * This balances a call to PushLayer and proceeds to blend the layer back
1728 * onto the background. This blend will blend the temporary surface back
1729 * onto the target in device space using POINT sampling and operator over.
1731 virtual void PopLayer() { MOZ_CRASH("GFX: PopLayer"); }
1734 * Perform an in-place blur operation. This is only supported on data draw
1737 virtual void Blur(const AlphaBoxBlur
& aBlur
);
1740 * Performs an in-place edge padding operation.
1741 * aRegion is specified in device space.
1743 virtual void PadEdges(const IntRegion
& aRegion
);
1746 * Performs an in-place buffer unrotation operation.
1748 virtual bool Unrotate(IntPoint aRotation
);
1751 * Create a SourceSurface optimized for use with this DrawTarget from
1752 * existing bitmap data in memory.
1754 * The SourceSurface does not take ownership of aData, and may be freed at any
1757 virtual already_AddRefed
<SourceSurface
> CreateSourceSurfaceFromData(
1758 unsigned char* aData
, const IntSize
& aSize
, int32_t aStride
,
1759 SurfaceFormat aFormat
) const = 0;
1762 * Create a SourceSurface optimized for use with this DrawTarget from an
1763 * arbitrary SourceSurface type supported by this backend. This may return
1764 * aSourceSurface or some other existing surface.
1766 virtual already_AddRefed
<SourceSurface
> OptimizeSourceSurface(
1767 SourceSurface
* aSurface
) const = 0;
1768 virtual already_AddRefed
<SourceSurface
> OptimizeSourceSurfaceForUnknownAlpha(
1769 SourceSurface
* aSurface
) const {
1770 return OptimizeSourceSurface(aSurface
);
1774 * Create a SourceSurface for a type of NativeSurface. This may fail if the
1775 * draw target does not know how to deal with the type of NativeSurface passed
1776 * in. If this succeeds, the SourceSurface takes the ownersip of the
1779 virtual already_AddRefed
<SourceSurface
> CreateSourceSurfaceFromNativeSurface(
1780 const NativeSurface
& aSurface
) const = 0;
1783 * Create a DrawTarget whose snapshot is optimized for use with this
1786 virtual already_AddRefed
<DrawTarget
> CreateSimilarDrawTarget(
1787 const IntSize
& aSize
, SurfaceFormat aFormat
) const = 0;
1790 * Create a DrawTarget whose backing surface is optimized for use with this
1793 virtual already_AddRefed
<DrawTarget
> CreateSimilarDrawTargetWithBacking(
1794 const IntSize
& aSize
, SurfaceFormat aFormat
) const {
1795 return CreateSimilarDrawTarget(aSize
, aFormat
);
1799 * Create a DrawTarget whose snapshot is optimized for use with this
1800 * DrawTarget and aFilter.
1801 * @param aSource is the FilterNode that that will be attached to this
1803 * @param aSourceRect is the source rect that will be passed to DrawFilter
1804 * @param aDestPoint is the dest point that will be passed to DrawFilter.
1806 virtual already_AddRefed
<DrawTarget
> CreateSimilarDrawTargetForFilter(
1807 const IntSize
& aSize
, SurfaceFormat aFormat
, FilterNode
* aFilter
,
1808 FilterNode
* aSource
, const Rect
& aSourceRect
, const Point
& aDestPoint
) {
1809 return CreateSimilarDrawTarget(aSize
, aFormat
);
1813 * Returns false if CreateSimilarDrawTarget would return null with the same
1814 * parameters. May return true even in cases where CreateSimilarDrawTarget
1815 * return null (i.e. this function returning false has meaning, but returning
1816 * true doesn't guarantee anything).
1818 virtual bool CanCreateSimilarDrawTarget(const IntSize
& aSize
,
1819 SurfaceFormat aFormat
) const {
1824 * Create a draw target optimized for drawing a shadow.
1826 * Note that aSigma is the blur radius that must be used when we draw the
1827 * shadow. Also note that this doesn't affect the size of the allocated
1828 * surface, the caller is still responsible for including the shadow area in
1831 virtual already_AddRefed
<DrawTarget
> CreateShadowDrawTarget(
1832 const IntSize
& aSize
, SurfaceFormat aFormat
, float aSigma
) const {
1833 return CreateSimilarDrawTarget(aSize
, aFormat
);
1837 * Create a similar DrawTarget in the same space as this DrawTarget whose
1838 * device size may be clipped based on the active clips intersected with
1839 * aBounds (if it is not empty).
1840 * aRect is a rectangle in user space.
1842 virtual RefPtr
<DrawTarget
> CreateClippedDrawTarget(const Rect
& aBounds
,
1843 SurfaceFormat aFormat
) = 0;
1846 * Create a similar draw target, but if the draw target is not backed by a
1847 * raster backend (for example, it is capturing or recording), force it to
1848 * create a raster target instead. This is intended for code that wants to
1849 * cache pixels, and would have no effect if it were caching a recording.
1851 virtual RefPtr
<DrawTarget
> CreateSimilarRasterTarget(
1852 const IntSize
& aSize
, SurfaceFormat aFormat
) const {
1853 return CreateSimilarDrawTarget(aSize
, aFormat
);
1857 * Create a path builder with the specified fillmode.
1859 * We need the fill mode up front because of Direct2D.
1860 * ID2D1SimplifiedGeometrySink requires the fill mode
1861 * to be set before calling BeginFigure().
1863 virtual already_AddRefed
<PathBuilder
> CreatePathBuilder(
1864 FillRule aFillRule
= FillRule::FILL_WINDING
) const = 0;
1867 * Create a GradientStops object that holds information about a set of
1868 * gradient stops, this object is required for linear or radial gradient
1869 * patterns to represent the color stops in the gradient.
1871 * @param aStops An array of gradient stops
1872 * @param aNumStops Number of stops in the array aStops
1873 * @param aExtendNone This describes how to extend the stop color outside of
1874 * the gradient area.
1876 virtual already_AddRefed
<GradientStops
> CreateGradientStops(
1877 GradientStop
* aStops
, uint32_t aNumStops
,
1878 ExtendMode aExtendMode
= ExtendMode::CLAMP
) const = 0;
1881 * Create a FilterNode object that can be used to apply a filter to various
1884 * @param aType Type of filter node to be created.
1886 virtual already_AddRefed
<FilterNode
> CreateFilter(FilterType aType
) = 0;
1888 Matrix
GetTransform() const { return mTransform
; }
1891 * Set a transform on the surface, this transform is applied at drawing time
1892 * to both the mask and source of the operation.
1894 * Performance note: For some backends it is expensive to change the current
1895 * transform (because transforms affect a lot of the parts of the pipeline,
1896 * so new transform change can result in a pipeline flush). To get around
1897 * this, DrawTarget implementations buffer transform changes and try to only
1898 * set the current transform on the backend when required. That tracking has
1899 * its own performance impact though, and ideally callers would be smart
1900 * enough not to require it. At a future date this method may stop this
1901 * doing transform buffering so, if you're a consumer, please try to be smart
1902 * about calling this method as little as possible. For example, instead of
1903 * concatenating a translation onto the current transform then calling
1904 * FillRect, try to integrate the translation into FillRect's aRect
1905 * argument's x/y offset.
1907 virtual void SetTransform(const Matrix
& aTransform
) {
1908 mTransform
= aTransform
;
1909 mTransformDirty
= true;
1912 inline void ConcatTransform(const Matrix
& aTransform
) {
1913 SetTransform(aTransform
* Matrix(GetTransform()));
1916 SurfaceFormat
GetFormat() const { return mFormat
; }
1918 /** Tries to get a native surface for a DrawTarget, this may fail if the
1919 * draw target cannot convert to this surface type.
1921 virtual void* GetNativeSurface(NativeSurfaceType aType
) { return nullptr; }
1923 virtual bool IsTiledDrawTarget() const { return false; }
1924 virtual bool SupportsRegionClipping() const { return true; }
1926 void AddUserData(UserDataKey
* key
, void* userData
, void (*destroy
)(void*)) {
1927 mUserData
.Add(key
, userData
, destroy
);
1929 void* GetUserData(UserDataKey
* key
) const { return mUserData
.Get(key
); }
1930 void* RemoveUserData(UserDataKey
* key
) { return mUserData
.Remove(key
); }
1932 /** Within this rectangle all pixels will be opaque by the time the result of
1933 * this DrawTarget is first used for drawing. Either by the underlying surface
1934 * being used as an input to external drawing, or Snapshot() being called.
1935 * This rectangle is specified in device space.
1937 void SetOpaqueRect(const IntRect
& aRect
) { mOpaqueRect
= aRect
; }
1939 const IntRect
& GetOpaqueRect() const { return mOpaqueRect
; }
1941 virtual bool IsCurrentGroupOpaque() {
1942 return GetFormat() == SurfaceFormat::B8G8R8X8
;
1945 virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA
) {
1946 mPermitSubpixelAA
= aPermitSubpixelAA
;
1949 bool GetPermitSubpixelAA() { return mPermitSubpixelAA
; }
1952 * Mark the end of an Item in a DrawTargetRecording. These markers
1953 * are used for merging recordings together.
1955 * This should only be called on the 'root' DrawTargetRecording.
1956 * Calling it on a child DrawTargetRecordings will cause confusion.
1958 * Note: this is a bit of a hack. It might be better to just recreate
1959 * the DrawTargetRecording.
1961 virtual void FlushItem(const IntRect
& aBounds
) {}
1964 * Ensures that no snapshot is still pointing to this DrawTarget's surface
1967 * This can be useful if the DrawTarget is wrapped around data that it does
1968 * not own, and for some reason the owner of the data has to make it
1969 * temporarily unavailable without the DrawTarget knowing about it. This can
1970 * cause costly surface copies, so it should not be used without a a good
1973 virtual void DetachAllSnapshots() = 0;
1976 * Remove all clips in the DrawTarget.
1978 virtual bool RemoveAllClips() { return false; }
1983 IntRect mOpaqueRect
;
1984 bool mTransformDirty
: 1;
1985 bool mPermitSubpixelAA
: 1;
1987 SurfaceFormat mFormat
;
1990 class DrawEventRecorder
: public external::AtomicRefCounted
<DrawEventRecorder
> {
1992 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorder
)
1993 virtual RecorderType
GetRecorderType() const { return RecorderType::UNKNOWN
; }
1994 // returns true if there were any items in the recording
1995 virtual bool Finish() = 0;
1996 virtual ~DrawEventRecorder() = default;
2000 RefPtr
<DrawTarget
> mDrawTarget
;
2001 IntPoint mTileOrigin
;
2010 LogForwarder
* mLogForwarder
;
2011 int32_t mMaxTextureSize
;
2012 int32_t mMaxAllocSize
;
2015 : mLogForwarder(nullptr),
2016 mMaxTextureSize(kReasonableSurfaceSize
),
2017 mMaxAllocSize(52000000) {}
2020 class GFX2D_API Factory
{
2021 using char_type
= filesystem::Path::value_type
;
2024 static void Init(const Config
& aConfig
);
2025 static void ShutDown();
2027 static bool HasSSE2();
2028 static bool HasSSE4();
2031 * Returns false if any of the following are true:
2033 * - the width/height of |sz| are less than or equal to zero
2034 * - the width/height of |sz| are greater than |limit|
2035 * - the number of bytes that need to be allocated for the surface is too
2036 * big to fit in an int32_t, or bigger than |allocLimit|, if specifed
2038 * To calculate the number of bytes that need to be allocated for the surface
2039 * this function makes the conservative assumption that there need to be
2040 * 4 bytes-per-pixel, and the stride alignment is 16 bytes.
2042 * The reason for using int32_t rather than uint32_t is again to be
2043 * conservative; some code has in the past and may in the future use signed
2044 * integers to store buffer lengths etc.
2046 static bool CheckSurfaceSize(const IntSize
& sz
, int32_t limit
= 0,
2047 int32_t allocLimit
= 0);
2049 /** Make sure the given dimension satisfies the CheckSurfaceSize and is
2050 * within 8k limit. The 8k value is chosen a bit randomly.
2052 static bool ReasonableSurfaceSize(const IntSize
& aSize
);
2054 static bool AllowedSurfaceSize(const IntSize
& aSize
);
2056 static already_AddRefed
<DrawTarget
> CreateDrawTargetForCairoSurface(
2057 cairo_surface_t
* aSurface
, const IntSize
& aSize
,
2058 SurfaceFormat
* aFormat
= nullptr);
2060 static already_AddRefed
<SourceSurface
> CreateSourceSurfaceForCairoSurface(
2061 cairo_surface_t
* aSurface
, const IntSize
& aSize
, SurfaceFormat aFormat
);
2063 static already_AddRefed
<DrawTarget
> CreateDrawTarget(BackendType aBackend
,
2064 const IntSize
& aSize
,
2065 SurfaceFormat aFormat
);
2067 static already_AddRefed
<PathBuilder
> CreatePathBuilder(
2068 BackendType aBackend
, FillRule aFillRule
= FillRule::FILL_WINDING
);
2071 * Create a simple PathBuilder, which uses SKIA backend.
2073 static already_AddRefed
<PathBuilder
> CreateSimplePathBuilder();
2075 static already_AddRefed
<DrawTarget
> CreateRecordingDrawTarget(
2076 DrawEventRecorder
* aRecorder
, DrawTarget
* aDT
, IntRect aRect
);
2078 static already_AddRefed
<DrawTarget
> CreateDrawTargetForData(
2079 BackendType aBackend
, unsigned char* aData
, const IntSize
& aSize
,
2080 int32_t aStride
, SurfaceFormat aFormat
, bool aUninitialized
= false);
2083 static already_AddRefed
<ScaledFont
> CreateScaledFontForMacFont(
2084 CGFontRef aCGFont
, const RefPtr
<UnscaledFont
>& aUnscaledFont
, Float aSize
,
2085 bool aUseFontSmoothing
= true, bool aApplySyntheticBold
= false,
2086 bool aHasColorGlyphs
= false);
2089 #ifdef MOZ_WIDGET_GTK
2090 static already_AddRefed
<ScaledFont
> CreateScaledFontForFontconfigFont(
2091 const RefPtr
<UnscaledFont
>& aUnscaledFont
, Float aSize
,
2092 RefPtr
<SharedFTFace
> aFace
, FcPattern
* aPattern
);
2095 #ifdef MOZ_WIDGET_ANDROID
2096 static already_AddRefed
<ScaledFont
> CreateScaledFontForFreeTypeFont(
2097 const RefPtr
<UnscaledFont
>& aUnscaledFont
, Float aSize
,
2098 RefPtr
<SharedFTFace
> aFace
, bool aApplySyntheticBold
= false);
2102 * This creates a NativeFontResource from TrueType data.
2104 * @param aData Pointer to the data
2105 * @param aSize Size of the TrueType data
2106 * @param aFontType Type of NativeFontResource that should be created.
2107 * @param aFontContext Optional native font context to be used to create the
2108 * NativeFontResource.
2109 * @return a NativeFontResource of nullptr if failed.
2111 static already_AddRefed
<NativeFontResource
> CreateNativeFontResource(
2112 uint8_t* aData
, uint32_t aSize
, FontType aFontType
,
2113 void* aFontContext
= nullptr);
2116 * This creates an unscaled font of the given type based on font descriptor
2117 * data retrieved from ScaledFont::GetFontDescriptor.
2119 static already_AddRefed
<UnscaledFont
> CreateUnscaledFontFromFontDescriptor(
2120 FontType aType
, const uint8_t* aData
, uint32_t aDataLength
,
2124 * This creates a simple data source surface for a certain size. It allocates
2125 * new memory for the surface. This memory is freed when the surface is
2126 * destroyed. The caller is responsible for handing the case where nullptr
2127 * is returned. The surface is not zeroed unless requested.
2129 static already_AddRefed
<DataSourceSurface
> CreateDataSourceSurface(
2130 const IntSize
& aSize
, SurfaceFormat aFormat
, bool aZero
= false);
2133 * This creates a simple data source surface for a certain size with a
2134 * specific stride, which must be large enough to fit all pixels.
2135 * It allocates new memory for the surface. This memory is freed when
2136 * the surface is destroyed. The caller is responsible for handling the case
2137 * where nullptr is returned. The surface is not zeroed unless requested.
2139 static already_AddRefed
<DataSourceSurface
> CreateDataSourceSurfaceWithStride(
2140 const IntSize
& aSize
, SurfaceFormat aFormat
, int32_t aStride
,
2141 bool aZero
= false);
2143 typedef void (*SourceSurfaceDeallocator
)(void* aClosure
);
2146 * This creates a simple data source surface for some existing data. It will
2147 * wrap this data and the data for this source surface.
2149 * We can provide a custom destroying function for |aData|. This will be
2150 * called in the surface dtor using |aDeallocator| and the |aClosure|. If
2151 * there are errors during construction(return a nullptr surface), the caller
2152 * is responsible for the deallocation.
2154 * If there is no destroying function, the caller is responsible for
2155 * deallocating the aData memory only after destruction of this
2156 * DataSourceSurface.
2158 static already_AddRefed
<DataSourceSurface
> CreateWrappingDataSourceSurface(
2159 uint8_t* aData
, int32_t aStride
, const IntSize
& aSize
,
2160 SurfaceFormat aFormat
, SourceSurfaceDeallocator aDeallocator
= nullptr,
2161 void* aClosure
= nullptr);
2163 static already_AddRefed
<DataSourceSurface
> CopyDataSourceSurface(
2164 DataSourceSurface
* aSource
);
2166 static void CopyDataSourceSurface(DataSourceSurface
* aSource
,
2167 DataSourceSurface
* aDest
);
2169 static uint32_t GetMaxSurfaceSize(BackendType aType
);
2171 static LogForwarder
* GetLogForwarder() {
2172 return sConfig
? sConfig
->mLogForwarder
: nullptr;
2176 static Config
* sConfig
;
2179 static void PurgeAllCaches();
2181 static already_AddRefed
<DrawTarget
> CreateOffsetDrawTarget(
2182 DrawTarget
* aDrawTarget
, IntPoint aTileOrigin
);
2184 static bool DoesBackendSupportDataDrawtarget(BackendType aType
);
2186 static void SetBGRSubpixelOrder(bool aBGR
);
2187 static bool GetBGRSubpixelOrder();
2190 static bool mBGRSubpixelOrder
;
2193 static already_AddRefed
<DrawTarget
> CreateDrawTargetWithSkCanvas(
2196 #ifdef MOZ_ENABLE_FREETYPE
2197 static void SetFTLibrary(FT_Library aFTLibrary
);
2198 static FT_Library
GetFTLibrary();
2200 static FT_Library
NewFTLibrary();
2201 static void ReleaseFTLibrary(FT_Library aFTLibrary
);
2202 static void LockFTLibrary(FT_Library aFTLibrary
);
2203 static void UnlockFTLibrary(FT_Library aFTLibrary
);
2205 static FT_Face
NewFTFace(FT_Library aFTLibrary
, const char* aFileName
,
2207 static already_AddRefed
<SharedFTFace
> NewSharedFTFace(FT_Library aFTLibrary
,
2208 const char* aFilename
,
2210 static FT_Face
NewFTFaceFromData(FT_Library aFTLibrary
, const uint8_t* aData
,
2211 size_t aDataSize
, int aFaceIndex
);
2212 static already_AddRefed
<SharedFTFace
> NewSharedFTFaceFromData(
2213 FT_Library aFTLibrary
, const uint8_t* aData
, size_t aDataSize
,
2214 int aFaceIndex
, SharedFTFaceData
* aSharedData
= nullptr);
2215 static void ReleaseFTFace(FT_Face aFace
);
2216 static FT_Error
LoadFTGlyph(FT_Face aFace
, uint32_t aGlyphIndex
,
2220 static FT_Library mFTLibrary
;
2221 static StaticMutex mFTLock
;
2227 static already_AddRefed
<DrawTarget
> CreateDrawTargetForD3D11Texture(
2228 ID3D11Texture2D
* aTexture
, SurfaceFormat aFormat
);
2231 * Attempts to create and install a D2D1 device from the supplied Direct3D11
2232 * device. Returns true on success, or false on failure and leaves the
2233 * D2D1/Direct3D11 devices unset.
2235 static bool SetDirect3D11Device(ID3D11Device
* aDevice
);
2236 static RefPtr
<ID3D11Device
> GetDirect3D11Device();
2237 static RefPtr
<ID2D1Device
> GetD2D1Device(uint32_t* aOutSeqNo
= nullptr);
2238 static bool HasD2D1Device();
2239 static RefPtr
<IDWriteFactory
> GetDWriteFactory();
2240 static RefPtr
<IDWriteFactory
> EnsureDWriteFactory();
2241 static bool SupportsD2D1();
2242 static RefPtr
<IDWriteFontCollection
> GetDWriteSystemFonts(
2243 bool aUpdate
= false);
2244 static RefPtr
<ID2D1DeviceContext
> GetD2DDeviceContext();
2246 static uint64_t GetD2DVRAMUsageDrawTarget();
2247 static uint64_t GetD2DVRAMUsageSourceSurface();
2248 static void D2DCleanup();
2250 static already_AddRefed
<ScaledFont
> CreateScaledFontForDWriteFont(
2251 IDWriteFontFace
* aFontFace
, const gfxFontStyle
* aStyle
,
2252 const RefPtr
<UnscaledFont
>& aUnscaledFont
, Float aSize
,
2253 bool aUseEmbeddedBitmap
, bool aUseMultistrikeBold
, bool aGDIForced
);
2255 static already_AddRefed
<ScaledFont
> CreateScaledFontForGDIFont(
2256 const void* aLogFont
, const RefPtr
<UnscaledFont
>& aUnscaledFont
,
2259 static void SetSystemTextQuality(uint8_t aQuality
);
2261 static already_AddRefed
<DataSourceSurface
>
2262 CreateBGRA8DataSourceSurfaceForD3D11Texture(ID3D11Texture2D
* aSrcTexture
,
2263 uint32_t aArrayIndex
= 0);
2265 static nsresult
CreateSdbForD3D11Texture(
2266 ID3D11Texture2D
* aSrcTexture
, const IntSize
& aSrcSize
,
2267 layers::SurfaceDescriptorBuffer
& aSdBuffer
,
2268 const std::function
<layers::MemoryOrShmem(uint32_t)>& aAllocate
);
2270 static bool ReadbackTexture(layers::TextureData
* aDestCpuTexture
,
2271 ID3D11Texture2D
* aSrcTexture
);
2273 static bool ReadbackTexture(DataSourceSurface
* aDestCpuTexture
,
2274 ID3D11Texture2D
* aSrcTexture
,
2275 uint32_t aArrayIndex
= 0);
2278 static StaticRefPtr
<ID2D1Device
> mD2D1Device
;
2279 static StaticRefPtr
<ID3D11Device
> mD3D11Device
;
2280 static StaticRefPtr
<IDWriteFactory
> mDWriteFactory
;
2281 static bool mDWriteFactoryInitialized
;
2282 static StaticRefPtr
<IDWriteFontCollection
> mDWriteSystemFonts
;
2283 static StaticRefPtr
<ID2D1DeviceContext
> mMTDC
;
2284 static StaticRefPtr
<ID2D1DeviceContext
> mOffMTDC
;
2286 static bool ReadbackTexture(uint8_t* aDestData
, int32_t aDestStride
,
2287 ID3D11Texture2D
* aSrcTexture
);
2289 // DestTextureT can be TextureData or DataSourceSurface.
2290 template <typename DestTextureT
>
2291 static bool ConvertSourceAndRetryReadback(DestTextureT
* aDestCpuTexture
,
2292 ID3D11Texture2D
* aSrcTexture
,
2293 uint32_t aArrayIndex
= 0);
2296 // This guards access to the singleton devices above, as well as the
2297 // singleton devices in DrawTargetD2D1.
2298 static StaticMutex mDeviceLock
;
2299 // This synchronizes access between different D2D drawtargets and their
2300 // implied dependency graph.
2301 static StaticMutex mDTDependencyLock
;
2303 friend class DrawTargetD2D1
;
2307 class MOZ_RAII AutoSerializeWithMoz2D final
{
2309 explicit AutoSerializeWithMoz2D(BackendType aBackendType
);
2310 ~AutoSerializeWithMoz2D();
2314 RefPtr
<ID2D1Multithread
> mMT
;
2319 } // namespace mozilla
2321 #endif // _MOZILLA_GFX_2D_H