Backed out 2 changesets (bug 1855992) for causing talos failures @ mozilla::net:...
[gecko.git] / gfx / 2d / 2D.h
blob745dcf20748db52ac0f1d788de07f61577d8a8f1
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
10 #include "Types.h"
11 #include "Point.h"
12 #include "Rect.h"
13 #include "Matrix.h"
14 #include "Quaternion.h"
15 #include "UserData.h"
16 #include "FontVariation.h"
17 #include <vector>
19 // GenericRefCountedBase allows us to hold on to refcounted objects of any type
20 // (contrary to RefCounted<T> which requires knowing the type T) and, in
21 // particular, without having a dependency on that type. This is used for
22 // DrawTargetSkia to be able to hold on to a GLContext.
23 #include "mozilla/GenericRefCounted.h"
24 #include "mozilla/MemoryReporting.h"
25 #include "mozilla/Path.h"
27 // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
28 // outparams using the &-operator. But it will have to do as there's no easy
29 // solution.
30 #include "mozilla/RefPtr.h"
31 #include "mozilla/StaticMutex.h"
32 #include "mozilla/StaticPtr.h"
33 #include "mozilla/ThreadSafeWeakPtr.h"
34 #include "mozilla/Atomics.h"
36 #include "mozilla/DebugOnly.h"
38 #include "nsRegionFwd.h"
40 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
41 # ifndef MOZ_ENABLE_FREETYPE
42 # define MOZ_ENABLE_FREETYPE
43 # endif
44 #endif
46 struct _cairo_surface;
47 typedef _cairo_surface cairo_surface_t;
49 struct _cairo_scaled_font;
50 typedef _cairo_scaled_font cairo_scaled_font_t;
52 struct FT_LibraryRec_;
53 typedef FT_LibraryRec_* FT_Library;
55 struct FT_FaceRec_;
56 typedef FT_FaceRec_* FT_Face;
58 typedef int FT_Error;
60 struct _FcPattern;
61 typedef _FcPattern FcPattern;
63 struct ID3D11Texture2D;
64 struct ID3D11Device;
65 struct ID2D1Device;
66 struct ID2D1DeviceContext;
67 struct ID2D1Multithread;
68 struct IDWriteFactory;
69 struct IDWriteRenderingParams;
70 struct IDWriteFontFace;
71 struct IDWriteFontCollection;
73 class SkCanvas;
74 struct gfxFontStyle;
76 struct CGContext;
77 typedef struct CGContext* CGContextRef;
79 struct CGFont;
80 typedef CGFont* CGFontRef;
82 namespace mozilla {
84 class Mutex;
86 namespace layers {
87 class TextureData;
90 namespace wr {
91 struct FontInstanceOptions;
92 struct FontInstancePlatformOptions;
93 } // namespace wr
95 namespace gfx {
96 class UnscaledFont;
97 class ScaledFont;
98 } // namespace gfx
100 namespace gfx {
102 class AlphaBoxBlur;
103 class ScaledFont;
104 class SourceSurface;
105 class DataSourceSurface;
106 class DrawTarget;
107 class DrawEventRecorder;
108 class FilterNode;
109 class LogForwarder;
111 struct NativeSurface {
112 NativeSurfaceType mType;
113 SurfaceFormat mFormat;
114 gfx::IntSize mSize;
115 void* mSurface;
119 * This structure is used to send draw options that are universal to all drawing
120 * operations.
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) {}
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. */
139 struct StoredStrokeOptions;
142 * This structure is used to send stroke options that are used in stroking
143 * operations.
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);
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.
174 StoredStrokeOptions* Clone() const;
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;
189 * Heap-allocated variation of StrokeOptions that ensures dash patterns are
190 * properly allocated and destroyed even if the source was stack-allocated.
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;
202 ~StoredStrokeOptions() {
203 if (mDashPattern) {
204 delete[] mDashPattern;
209 inline StoredStrokeOptions* StrokeOptions::Clone() const {
210 return new StoredStrokeOptions(*this);
214 * This structure supplies additional options for calls to DrawSurface.
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) {}
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. */
233 * ShadowOptions supplies options necessary for describing the appearance of a
234 * a shadow in draw calls that use shadowing.
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) {}
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. */
246 int32_t BlurRadius() const;
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.
254 class GradientStops : public SupportsThreadSafeWeakPtr<GradientStops> {
255 public:
256 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops)
257 virtual ~GradientStops() = default;
259 virtual BackendType GetBackendType() const = 0;
260 virtual bool IsValid() const { return true; }
262 protected:
263 GradientStops() = default;
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.
272 class Pattern {
273 public:
274 virtual ~Pattern() = default;
276 virtual PatternType GetType() const = 0;
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; }
282 /** Whether the pattern holds an internal weak reference. */
283 virtual bool IsWeak() const { return false; }
285 /** Whether any internal weak references still point to a target. */
286 virtual bool IsValid() const { return true; }
288 /** Determine if the pattern type and values exactly match. */
289 virtual bool operator==(const Pattern& aOther) const = 0;
291 bool operator!=(const Pattern& aOther) const { return !(*this == aOther); }
293 protected:
294 Pattern() = default;
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;
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();
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) {}
316 PatternType GetType() const override { return PatternType::COLOR; }
318 Pattern* CloneWeak() const override { return new ColorPattern(mColor); }
320 bool operator==(const Pattern& aOther) const override {
321 if (aOther.GetType() != PatternType::COLOR) {
322 return false;
324 const ColorPattern& other = static_cast<const ColorPattern&>(aOther);
325 return mColor == other.mColor;
328 DeviceColor mColor;
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.
336 template <template <typename> typename REF = RefPtr>
337 class LinearGradientPatternT : public Pattern {
338 typedef LinearGradientPatternT<ThreadSafeWeakPtr> Weak;
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) {}
350 PatternType GetType() const override { return PatternType::LINEAR_GRADIENT; }
352 Pattern* CloneWeak() const override {
353 return new Weak(mBegin, mEnd, do_AddRef(mStops), mMatrix);
356 bool IsWeak() const override {
357 return std::is_same<decltype(*this), Weak>::value;
360 bool IsValid() const override { return IsRefValid(mStops); }
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);
368 bool operator==(const Pattern& aOther) const override {
369 if (aOther.GetType() != PatternType::LINEAR_GRADIENT) {
370 return false;
372 return aOther.IsWeak()
373 ? *this == static_cast<const Weak&>(aOther)
374 : *this == static_cast<const LinearGradientPatternT<>&>(aOther);
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 */
388 typedef LinearGradientPatternT<> LinearGradientPattern;
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.
395 template <template <typename> typename REF = RefPtr>
396 class RadialGradientPatternT : public Pattern {
397 typedef RadialGradientPatternT<ThreadSafeWeakPtr> Weak;
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) {}
412 PatternType GetType() const override { return PatternType::RADIAL_GRADIENT; }
414 Pattern* CloneWeak() const override {
415 return new Weak(mCenter1, mCenter2, mRadius1, mRadius2, do_AddRef(mStops),
416 mMatrix);
419 bool IsWeak() const override {
420 return std::is_same<decltype(*this), Weak>::value;
423 bool IsValid() const override { return IsRefValid(mStops); }
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);
432 bool operator==(const Pattern& aOther) const override {
433 if (aOther.GetType() != PatternType::RADIAL_GRADIENT) {
434 return false;
436 return aOther.IsWeak()
437 ? *this == static_cast<const Weak&>(aOther)
438 : *this == static_cast<const RadialGradientPatternT<>&>(aOther);
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
451 typedef RadialGradientPatternT<> RadialGradientPattern;
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.
458 template <template <typename> typename REF = RefPtr>
459 class ConicGradientPatternT : public Pattern {
460 typedef ConicGradientPatternT<ThreadSafeWeakPtr> Weak;
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) {}
474 PatternType GetType() const override { return PatternType::CONIC_GRADIENT; }
476 Pattern* CloneWeak() const override {
477 return new Weak(mCenter, mAngle, mStartOffset, mEndOffset,
478 do_AddRef(mStops), mMatrix);
481 bool IsWeak() const override {
482 return std::is_same<decltype(*this), Weak>::value;
485 bool IsValid() const override { return IsRefValid(mStops); }
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);
495 bool operator==(const Pattern& aOther) const override {
496 if (aOther.GetType() != PatternType::CONIC_GRADIENT) {
497 return false;
499 return aOther.IsWeak()
500 ? *this == static_cast<const Weak&>(aOther)
501 : *this == static_cast<const ConicGradientPatternT<>&>(aOther);
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
514 typedef ConicGradientPatternT<> ConicGradientPattern;
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.
520 template <template <typename> typename REF = RefPtr>
521 class SurfacePatternT : public Pattern {
522 typedef SurfacePatternT<ThreadSafeWeakPtr> Weak;
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) {}
536 PatternType GetType() const override { return PatternType::SURFACE; }
538 Pattern* CloneWeak() const override {
539 return new Weak(do_AddRef(mSurface), mExtendMode, mMatrix, mSamplingFilter,
540 mSamplingRect);
543 bool IsWeak() const override {
544 return std::is_same<decltype(*this), Weak>::value;
547 bool IsValid() const override { return IsRefValid(mSurface); }
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);
557 bool operator==(const Pattern& aOther) const override {
558 if (aOther.GetType() != PatternType::SURFACE) {
559 return false;
561 return aOther.IsWeak()
562 ? *this == static_cast<const Weak&>(aOther)
563 : *this == static_cast<const SurfacePatternT<>&>(aOther);
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
573 IntRect mSamplingRect; /**< Rect that must not be sampled outside of,
574 or an empty rect if none has been
575 specified. */
578 typedef SurfacePatternT<> SurfacePattern;
580 class StoredPattern;
582 static const int32_t kReasonableSurfaceSize = 8192;
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.
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.
594 class SourceSurface : public SupportsThreadSafeWeakPtr<SourceSurface> {
595 public:
596 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface)
597 virtual ~SourceSurface() = default;
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;
607 * Structure containing memory size information for the surface.
609 struct SizeOfInfo {
610 SizeOfInfo()
611 : mHeapBytes(0),
612 mNonHeapBytes(0),
613 mUnknownBytes(0),
614 mExternalHandles(0),
615 mExternalId(0),
616 mTypes(0) {}
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;
626 mTypes |= aOther.mTypes;
629 void AddType(SurfaceType aType) { mTypes |= 1 << uint32_t(aType); }
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.
640 * Get the size information of the underlying data buffer.
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);
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.
656 virtual bool IsValid() const { return true; }
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).
663 virtual bool Equals(SourceSurface* aOther, bool aSymmetric = true) {
664 return this == aOther ||
665 (aSymmetric && aOther && aOther->Equals(this, false));
669 * This function will return true if the surface type matches that of a
670 * DataSourceSurface and if GetDataSurface will return the same object.
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;
689 * This function will get a DataSourceSurface for this surface, a
690 * DataSourceSurface's data can be accessed directly.
692 virtual already_AddRefed<DataSourceSurface> GetDataSurface() = 0;
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();
700 /** Tries to get this SourceSurface's native surface. This will fail if aType
701 * is not the type of this SourceSurface's native surface.
703 virtual void* GetNativeSurface(NativeSurfaceType aType) { return nullptr; }
705 void AddUserData(UserDataKey* key, void* userData, void (*destroy)(void*)) {
706 mUserData.Add(key, userData, destroy);
708 void* GetUserData(UserDataKey* key) const { return mUserData.Get(key); }
709 void RemoveUserData(UserDataKey* key) { mUserData.RemoveAndDestroy(key); }
711 /** Tries to extract an optimal subrect for the surface. This may fail if the
712 * request can't be satisfied.
714 virtual already_AddRefed<SourceSurface> ExtractSubrect(const IntRect& aRect) {
715 return nullptr;
718 protected:
719 friend class StoredPattern;
721 ThreadSafeUserData mUserData;
724 class DataSourceSurface : public SourceSurface {
725 public:
726 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurface, override)
727 DataSourceSurface() : mMapCount(0) {}
729 #ifdef DEBUG
730 virtual ~DataSourceSurface() { MOZ_ASSERT(mMapCount == 0); }
731 #endif
733 struct MappedSurface {
734 uint8_t* mData = nullptr;
735 int32_t mStride = 0;
738 enum MapType { READ, WRITE, READ_WRITE };
741 * This is a scoped version of Map(). Map() is called in the constructor and
742 * Unmap() in the destructor. Use this for automatic unmapping of your data
743 * surfaces.
745 * Use IsMapped() to verify whether Map() succeeded or not.
747 class ScopedMap final {
748 public:
749 ScopedMap(DataSourceSurface* aSurface, MapType aType)
750 : mSurface(aSurface), mIsMapped(aSurface->Map(aType, &mMap)) {}
752 ScopedMap(ScopedMap&& aOther)
753 : mSurface(std::move(aOther.mSurface)),
754 mMap(aOther.mMap),
755 mIsMapped(aOther.mIsMapped) {
756 aOther.mMap.mData = nullptr;
757 aOther.mIsMapped = false;
760 ScopedMap& operator=(ScopedMap&& aOther) {
761 if (mIsMapped) {
762 mSurface->Unmap();
764 mSurface = std::move(aOther.mSurface);
765 mMap = aOther.mMap;
766 mIsMapped = aOther.mIsMapped;
767 aOther.mMap.mData = nullptr;
768 aOther.mIsMapped = false;
769 return *this;
772 ~ScopedMap() {
773 if (mIsMapped) {
774 mSurface->Unmap();
778 uint8_t* GetData() const {
779 MOZ_ASSERT(mIsMapped);
780 return mMap.mData;
783 int32_t GetStride() const {
784 MOZ_ASSERT(mIsMapped);
785 return mMap.mStride;
788 const MappedSurface* GetMappedSurface() const {
789 MOZ_ASSERT(mIsMapped);
790 return &mMap;
793 const DataSourceSurface* GetSurface() const {
794 MOZ_ASSERT(mIsMapped);
795 return mSurface;
798 bool IsMapped() const { return mIsMapped; }
800 private:
801 ScopedMap(const ScopedMap& aOther) = delete;
802 ScopedMap& operator=(const ScopedMap& aOther) = delete;
804 RefPtr<DataSourceSurface> mSurface;
805 MappedSurface mMap;
806 bool mIsMapped;
809 SurfaceType GetType() const override { return SurfaceType::DATA; }
810 /** @deprecated
811 * Get the raw bitmap data of the surface.
812 * Can return null if there was OOM allocating surface data.
814 * Deprecated means you shouldn't be using this!! Use Map instead.
815 * Please deny any reviews which add calls to this!
817 virtual uint8_t* GetData() = 0;
819 /** @deprecated
820 * Stride of the surface, distance in bytes between the start of the image
821 * data belonging to row y and row y+1. This may be negative.
822 * Can return 0 if there was OOM allocating surface data.
824 virtual int32_t Stride() = 0;
827 * The caller is responsible for ensuring aMappedSurface is not null.
828 // Althought Map (and Moz2D in general) isn't normally threadsafe,
829 // we want to allow it for SourceSurfaceRawData since it should
830 // always be fine (for reading at least).
832 // This is the same as the base class implementation except using
833 // mMapCount instead of mIsMapped since that breaks for multithread.
835 // Once mfbt supports Monitors we should implement proper read/write
836 // locking to prevent write races.
838 virtual bool Map(MapType, MappedSurface* aMappedSurface) {
839 aMappedSurface->mData = GetData();
840 aMappedSurface->mStride = Stride();
841 bool success = !!aMappedSurface->mData;
842 if (success) {
843 mMapCount++;
845 return success;
848 virtual void Unmap() {
849 mMapCount--;
850 MOZ_ASSERT(mMapCount >= 0);
854 * Returns a DataSourceSurface with the same data as this one, but
855 * guaranteed to have surface->GetType() == SurfaceType::DATA.
857 * The returning surface might be null, because of OOM or gfx device reset.
858 * The caller needs to do null-check before using it.
860 already_AddRefed<DataSourceSurface> GetDataSurface() override;
863 * Returns whether or not the data was allocated on the heap. This should
864 * be used to determine if the memory needs to be cleared to 0.
866 virtual bool OnHeap() const { return true; }
869 * Yields a dirty rect of what has changed since it was last called.
871 virtual Maybe<IntRect> TakeDirtyRect() { return Nothing(); }
874 * Indicate a region which has changed in the surface.
876 virtual void Invalidate(const IntRect& aDirtyRect) {}
878 protected:
879 Atomic<int32_t> mMapCount;
882 /** This is an abstract object that accepts path segments. */
883 class PathSink : public RefCounted<PathSink> {
884 public:
885 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathSink)
886 virtual ~PathSink() = default;
888 /** Move the current point in the path, any figure currently being drawn will
889 * be considered closed during fill operations, however when stroking the
890 * closing line segment will not be drawn.
892 virtual void MoveTo(const Point& aPoint) = 0;
893 /** Add a linesegment to the current figure */
894 virtual void LineTo(const Point& aPoint) = 0;
895 /** Add a cubic bezier curve to the current figure */
896 virtual void BezierTo(const Point& aCP1, const Point& aCP2,
897 const Point& aCP3) = 0;
898 /** Add a quadratic bezier curve to the current figure */
899 virtual void QuadraticBezierTo(const Point& aCP1, const Point& aCP2) = 0;
900 /** Close the current figure, this will essentially generate a line segment
901 * from the current point to the starting point for the current figure
903 virtual void Close() = 0;
904 /** Add an arc to the current figure */
905 virtual void Arc(const Point& aOrigin, float aRadius, float aStartAngle,
906 float aEndAngle, bool aAntiClockwise = false) = 0;
908 virtual Point CurrentPoint() const { return mCurrentPoint; }
910 virtual Point BeginPoint() const { return mBeginPoint; }
912 virtual void SetCurrentPoint(const Point& aPoint) { mCurrentPoint = aPoint; }
914 virtual void SetBeginPoint(const Point& aPoint) { mBeginPoint = aPoint; }
916 protected:
917 /** Point the current subpath is at - or where the next subpath will start
918 * if there is no active subpath.
920 Point mCurrentPoint;
922 /** Position of the previous MoveTo operation. */
923 Point mBeginPoint;
926 class PathBuilder;
927 class FlattenedPath;
929 /** The path class is used to create (sets of) figures of any shape that can be
930 * filled or stroked to a DrawTarget
932 class Path : public external::AtomicRefCounted<Path> {
933 public:
934 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(Path)
935 virtual ~Path();
937 virtual BackendType GetBackendType() const = 0;
939 /** This returns a PathBuilder object that contains a copy of the contents of
940 * this path and is still writable.
942 inline already_AddRefed<PathBuilder> CopyToBuilder() const {
943 return CopyToBuilder(GetFillRule());
945 inline already_AddRefed<PathBuilder> TransformedCopyToBuilder(
946 const Matrix& aTransform) const {
947 return TransformedCopyToBuilder(aTransform, GetFillRule());
949 /** This returns a PathBuilder object that contains a copy of the contents of
950 * this path, converted to use the specified FillRule, and still writable.
952 virtual already_AddRefed<PathBuilder> CopyToBuilder(
953 FillRule aFillRule) const = 0;
954 virtual already_AddRefed<PathBuilder> TransformedCopyToBuilder(
955 const Matrix& aTransform, FillRule aFillRule) const = 0;
957 /** This function checks if a point lies within a path. It allows passing a
958 * transform that will transform the path to the coordinate space in which
959 * aPoint is given.
961 virtual bool ContainsPoint(const Point& aPoint,
962 const Matrix& aTransform) const = 0;
964 /** This function checks if a point lies within the stroke of a path using the
965 * specified strokeoptions. It allows passing a transform that will transform
966 * the path to the coordinate space in which aPoint is given.
968 virtual bool StrokeContainsPoint(const StrokeOptions& aStrokeOptions,
969 const Point& aPoint,
970 const Matrix& aTransform) const = 0;
972 /** This functions gets the bounds of this path. These bounds are not
973 * guaranteed to be tight. A transform may be specified that gives the bounds
974 * after application of the transform.
976 virtual Rect GetBounds(const Matrix& aTransform = Matrix()) const = 0;
978 /** This function gets the bounds of the stroke of this path using the
979 * specified strokeoptions. These bounds are not guaranteed to be tight.
980 * A transform may be specified that gives the bounds after application of
981 * the transform.
983 virtual Rect GetStrokedBounds(const StrokeOptions& aStrokeOptions,
984 const Matrix& aTransform = Matrix()) const = 0;
986 /** Gets conservative bounds for the path, optionally stroked or transformed.
987 * This function will prioritize speed of computation over tightness of the
988 * computed bounds if the backend supports the distinction.
990 virtual Rect GetFastBounds(
991 const Matrix& aTransform = Matrix(),
992 const StrokeOptions* aStrokeOptions = nullptr) const;
994 /** Take the contents of this path and stream it to another sink, this works
995 * regardless of the backend that might be used for the destination sink.
997 virtual void StreamToSink(PathSink* aSink) const = 0;
999 /** This gets the fillrule this path's builder was created with. This is not
1000 * mutable.
1002 virtual FillRule GetFillRule() const = 0;
1004 virtual Float ComputeLength();
1006 virtual Maybe<Rect> AsRect() const { return Nothing(); }
1008 virtual Point ComputePointAtLength(Float aLength, Point* aTangent = nullptr);
1010 virtual bool IsEmpty() const = 0;
1012 protected:
1013 Path();
1014 void EnsureFlattenedPath();
1016 RefPtr<FlattenedPath> mFlattenedPath;
1019 /** The PathBuilder class allows path creation. Once finish is called on the
1020 * pathbuilder it may no longer be written to.
1022 class PathBuilder : public PathSink {
1023 public:
1024 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilder, override)
1025 /** Finish writing to the path and return a Path object that can be used for
1026 * drawing. Future use of the builder results in a crash!
1028 virtual already_AddRefed<Path> Finish() = 0;
1030 virtual BackendType GetBackendType() const = 0;
1032 virtual bool IsActive() const = 0;
1035 struct Glyph {
1036 uint32_t mIndex;
1037 Point mPosition;
1040 static inline bool operator==(const Glyph& aOne, const Glyph& aOther) {
1041 return aOne.mIndex == aOther.mIndex && aOne.mPosition == aOther.mPosition;
1044 /** This class functions as a glyph buffer that can be drawn to a DrawTarget.
1045 * @todo XXX - This should probably contain the guts of gfxTextRun in the future
1046 * as roc suggested. But for now it's a simple container for a glyph vector.
1048 struct GlyphBuffer {
1049 const Glyph*
1050 mGlyphs; //!< A pointer to a buffer of glyphs. Managed by the caller.
1051 uint32_t mNumGlyphs; //!< Number of glyphs mGlyphs points to.
1054 #ifdef MOZ_ENABLE_FREETYPE
1055 class SharedFTFace;
1057 /** SharedFTFaceData abstracts data that may be used to back a SharedFTFace.
1058 * Its main function is to manage the lifetime of the data and ensure that it
1059 * lasts as long as the face.
1061 class SharedFTFaceData {
1062 public:
1063 /** Utility for creating a new face from this data. */
1064 virtual already_AddRefed<SharedFTFace> CloneFace(int aFaceIndex = 0) {
1065 return nullptr;
1067 /** Binds the data's lifetime to the face. */
1068 virtual void BindData() = 0;
1069 /** Signals that the data is no longer needed by a face. */
1070 virtual void ReleaseData() = 0;
1073 /** Wrapper class for ref-counted SharedFTFaceData that handles calling the
1074 * appropriate ref-counting methods
1076 template <class T>
1077 class SharedFTFaceRefCountedData : public SharedFTFaceData {
1078 public:
1079 void BindData() { static_cast<T*>(this)->AddRef(); }
1080 void ReleaseData() { static_cast<T*>(this)->Release(); }
1083 // Helper class used for clearing out user font data when FT font
1084 // face is destroyed. Since multiple faces may use the same data, be
1085 // careful to assure that the data is only cleared out when all uses
1086 // expire. The font entry object contains a refptr to FTUserFontData and
1087 // each FT face created from that font entry contains a refptr to that
1088 // same FTUserFontData object.
1089 // This is also attached to FT faces for installed fonts (recording the
1090 // filename, rather than storing the font data) if variations are present.
1091 class FTUserFontData final
1092 : public mozilla::gfx::SharedFTFaceRefCountedData<FTUserFontData> {
1093 public:
1094 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FTUserFontData)
1096 FTUserFontData(const uint8_t* aData, uint32_t aLength)
1097 : mFontData(aData), mLength(aLength) {}
1098 explicit FTUserFontData(const char* aFilename) : mFilename(aFilename) {}
1100 const uint8_t* FontData() const { return mFontData; }
1102 already_AddRefed<mozilla::gfx::SharedFTFace> CloneFace(
1103 int aFaceIndex = 0) override;
1105 private:
1106 ~FTUserFontData() {
1107 if (mFontData) {
1108 free((void*)mFontData);
1112 std::string mFilename;
1113 const uint8_t* mFontData = nullptr;
1114 uint32_t mLength = 0;
1117 /** SharedFTFace is a shared wrapper around an FT_Face. It is ref-counted,
1118 * unlike FT_Face itself, so that it may be shared among many users with
1119 * RefPtr. Users should take care to lock SharedFTFace before accessing any
1120 * FT_Face fields that may change to ensure exclusive access to it. It also
1121 * allows backing data's lifetime to be bound to it via SharedFTFaceData so
1122 * that the data will not disappear before the face does.
1124 class SharedFTFace : public external::AtomicRefCounted<SharedFTFace> {
1125 public:
1126 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SharedFTFace)
1128 explicit SharedFTFace(FT_Face aFace, SharedFTFaceData* aData);
1129 virtual ~SharedFTFace();
1131 FT_Face GetFace() const { return mFace; }
1132 SharedFTFaceData* GetData() const { return mData; }
1134 /** Locks the face for exclusive access by a given owner. Returns false if
1135 * the given owner is acquiring the lock for the first time, and true if
1136 * the owner was the prior owner of the lock. Thus the return value can be
1137 * used to do owner-specific initialization of the FT face such as setting
1138 * a size or transform that may have been invalidated by a previous owner.
1139 * If no owner is given, then the user should avoid modifying any state on
1140 * the face so as not to invalidate the prior owner's modification.
1142 bool Lock(const void* aOwner = nullptr) MOZ_CAPABILITY_ACQUIRE(mLock) {
1143 mLock.Lock();
1144 return !aOwner || mLastLockOwner.exchange(aOwner) == aOwner;
1146 void Unlock() MOZ_CAPABILITY_RELEASE(mLock) { mLock.Unlock(); }
1148 /** Should be called when a lock owner is destroyed so that we don't have
1149 * a dangling pointer to a destroyed owner.
1151 void ForgetLockOwner(const void* aOwner) {
1152 if (aOwner) {
1153 mLastLockOwner.compareExchange(aOwner, nullptr);
1157 private:
1158 FT_Face mFace;
1159 SharedFTFaceData* mData;
1160 Mutex mLock;
1161 // Remember the last owner of the lock, even after unlocking, to allow users
1162 // to avoid reinitializing state on the FT face if the last owner hasn't
1163 // changed by the next time it is locked with the same owner.
1164 Atomic<const void*> mLastLockOwner;
1166 #endif
1168 class UnscaledFont : public SupportsThreadSafeWeakPtr<UnscaledFont> {
1169 public:
1170 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFont)
1172 virtual ~UnscaledFont();
1174 virtual FontType GetType() const = 0;
1176 static uint32_t DeletionCounter() { return sDeletionCounter; }
1178 typedef void (*FontFileDataOutput)(const uint8_t* aData, uint32_t aLength,
1179 uint32_t aIndex, void* aBaton);
1180 typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength,
1181 void* aBaton);
1182 typedef void (*FontDescriptorOutput)(const uint8_t* aData, uint32_t aLength,
1183 uint32_t aIndex, void* aBaton);
1185 virtual bool GetFontFileData(FontFileDataOutput, void*) { return false; }
1187 virtual bool GetFontInstanceData(FontInstanceDataOutput, void*) {
1188 return false;
1191 virtual bool GetFontDescriptor(FontDescriptorOutput, void*) { return false; }
1193 virtual already_AddRefed<ScaledFont> CreateScaledFont(
1194 Float aGlyphSize, const uint8_t* aInstanceData,
1195 uint32_t aInstanceDataLength, const FontVariation* aVariations,
1196 uint32_t aNumVariations) {
1197 return nullptr;
1200 virtual already_AddRefed<ScaledFont> CreateScaledFontFromWRFont(
1201 Float aGlyphSize, const wr::FontInstanceOptions* aOptions,
1202 const wr::FontInstancePlatformOptions* aPlatformOptions,
1203 const FontVariation* aVariations, uint32_t aNumVariations) {
1204 return CreateScaledFont(aGlyphSize, nullptr, 0, aVariations,
1205 aNumVariations);
1208 protected:
1209 UnscaledFont() = default;
1211 private:
1212 static Atomic<uint32_t> sDeletionCounter;
1215 /** This class is an abstraction of a backend/platform specific font object
1216 * at a particular size. It is passed into text drawing calls to describe
1217 * the font used for the drawing call.
1219 class ScaledFont : public SupportsThreadSafeWeakPtr<ScaledFont> {
1220 public:
1221 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
1223 virtual ~ScaledFont();
1225 virtual FontType GetType() const = 0;
1226 virtual Float GetSize() const = 0;
1227 virtual AntialiasMode GetDefaultAAMode() { return AntialiasMode::DEFAULT; }
1229 static uint32_t DeletionCounter() { return sDeletionCounter; }
1231 /** This allows getting a path that describes the outline of a set of glyphs.
1232 * A target is passed in so that the guarantee is made the returned path
1233 * can be used with any DrawTarget that has the same backend as the one
1234 * passed in.
1236 virtual already_AddRefed<Path> GetPathForGlyphs(
1237 const GlyphBuffer& aBuffer, const DrawTarget* aTarget) = 0;
1239 /** This copies the path describing the glyphs into a PathBuilder. We use this
1240 * API rather than a generic API to append paths because it allows easier
1241 * implementation in some backends, and more efficient implementation in
1242 * others.
1244 virtual void CopyGlyphsToBuilder(const GlyphBuffer& aBuffer,
1245 PathBuilder* aBuilder,
1246 const Matrix* aTransformHint = nullptr) = 0;
1248 typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength,
1249 const FontVariation* aVariations,
1250 uint32_t aNumVariations, void* aBaton);
1252 virtual bool GetFontInstanceData(FontInstanceDataOutput, void*) {
1253 return false;
1256 virtual bool GetWRFontInstanceOptions(
1257 Maybe<wr::FontInstanceOptions>* aOutOptions,
1258 Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
1259 std::vector<FontVariation>* aOutVariations) {
1260 return false;
1263 virtual bool CanSerialize() { return false; }
1265 virtual bool HasVariationSettings() { return false; }
1267 virtual bool MayUseBitmaps() { return false; }
1269 virtual bool UseSubpixelPosition() const { return false; }
1271 void AddUserData(UserDataKey* key, void* userData, void (*destroy)(void*)) {
1272 mUserData.Add(key, userData, destroy);
1274 void* GetUserData(UserDataKey* key) { return mUserData.Get(key); }
1276 void RemoveUserData(UserDataKey* key) { mUserData.RemoveAndDestroy(key); }
1278 const RefPtr<UnscaledFont>& GetUnscaledFont() const { return mUnscaledFont; }
1280 virtual cairo_scaled_font_t* GetCairoScaledFont() { return nullptr; }
1282 Float GetSyntheticObliqueAngle() const { return mSyntheticObliqueAngle; }
1283 void SetSyntheticObliqueAngle(Float aAngle) {
1284 mSyntheticObliqueAngle = aAngle;
1287 protected:
1288 explicit ScaledFont(const RefPtr<UnscaledFont>& aUnscaledFont)
1289 : mUnscaledFont(aUnscaledFont), mSyntheticObliqueAngle(0.0f) {}
1291 ThreadSafeUserData mUserData;
1292 RefPtr<UnscaledFont> mUnscaledFont;
1293 Float mSyntheticObliqueAngle;
1295 private:
1296 static Atomic<uint32_t> sDeletionCounter;
1300 * Derived classes hold a native font resource from which to create
1301 * ScaledFonts.
1303 class NativeFontResource
1304 : public external::AtomicRefCounted<NativeFontResource> {
1305 public:
1306 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResource)
1309 * Creates a UnscaledFont using the font corresponding to the index.
1311 * @param aIndex index for the font within the resource.
1312 * @param aInstanceData pointer to read-only buffer of any available instance
1313 * data.
1314 * @param aInstanceDataLength the size of the instance data.
1315 * @return an already_addrefed UnscaledFont, containing nullptr if failed.
1317 virtual already_AddRefed<UnscaledFont> CreateUnscaledFont(
1318 uint32_t aIndex, const uint8_t* aInstanceData,
1319 uint32_t aInstanceDataLength) = 0;
1321 NativeFontResource(size_t aDataLength);
1322 virtual ~NativeFontResource();
1324 static void RegisterMemoryReporter();
1326 private:
1327 size_t mDataLength;
1330 /** This is the main class used for all the drawing. It is created through the
1331 * factory and accepts drawing commands. The results of drawing to a target
1332 * may be used either through a Snapshot or by flushing the target and directly
1333 * accessing the backing store a DrawTarget was created with.
1335 class DrawTarget : public external::AtomicRefCounted<DrawTarget> {
1336 public:
1337 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget)
1338 DrawTarget()
1339 : mTransformDirty(false),
1340 mPermitSubpixelAA(false),
1341 mFormat(SurfaceFormat::UNKNOWN) {}
1342 virtual ~DrawTarget() = default;
1344 virtual bool IsValid() const { return true; };
1345 virtual DrawTargetType GetType() const = 0;
1347 virtual BackendType GetBackendType() const = 0;
1349 virtual bool IsRecording() const { return false; }
1352 * Method to generate hyperlink in PDF output (with appropriate backend).
1354 virtual void Link(const char* aDestination, const Rect& aRect) {}
1355 virtual void Destination(const char* aDestination, const Point& aPoint) {}
1358 * Returns a SourceSurface which is a snapshot of the current contents of the
1359 * DrawTarget. Multiple calls to Snapshot() without any drawing operations in
1360 * between will normally return the same SourceSurface object.
1362 virtual already_AddRefed<SourceSurface> Snapshot() = 0;
1365 * Returns a SourceSurface which wraps the buffer backing the DrawTarget. The
1366 * contents of the buffer may change if there are drawing operations after
1367 * calling but only guarantees that it reflects the state at the time it was
1368 * called.
1370 virtual already_AddRefed<SourceSurface> GetBackingSurface() {
1371 return Snapshot();
1374 // Snapshots the contents and returns an alpha mask
1375 // based on the RGB values.
1376 virtual already_AddRefed<SourceSurface> IntoLuminanceSource(
1377 LuminanceType aLuminanceType, float aOpacity);
1378 virtual IntSize GetSize() const = 0;
1379 virtual IntRect GetRect() const { return IntRect(IntPoint(0, 0), GetSize()); }
1382 * If possible returns the bits to this DrawTarget for direct manipulation.
1383 * While the bits is locked any modifications to this DrawTarget is forbidden.
1384 * Release takes the original data pointer for safety.
1386 virtual bool LockBits(uint8_t** aData, IntSize* aSize, int32_t* aStride,
1387 SurfaceFormat* aFormat, IntPoint* aOrigin = nullptr) {
1388 return false;
1390 virtual void ReleaseBits(uint8_t* aData) {}
1392 /** Ensure that the DrawTarget backend has flushed all drawing operations to
1393 * this draw target. This must be called before using the backing surface of
1394 * this draw target outside of GFX 2D code.
1396 virtual void Flush() = 0;
1399 * Draw a surface to the draw target. Possibly doing partial drawing or
1400 * applying scaling. No sampling happens outside the source.
1402 * @param aSurface Source surface to draw
1403 * @param aDest Destination rectangle that this drawing operation should draw
1404 * to
1405 * @param aSource Source rectangle in aSurface coordinates, this area of
1406 * aSurface
1407 * will be stretched to the size of aDest.
1408 * @param aOptions General draw options that are applied to the operation
1409 * @param aSurfOptions DrawSurface options that are applied
1411 virtual void DrawSurface(
1412 SourceSurface* aSurface, const Rect& aDest, const Rect& aSource,
1413 const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(),
1414 const DrawOptions& aOptions = DrawOptions()) = 0;
1417 * Draw a surface to the draw target, when the surface will be available
1418 * at a later time. This is only valid for recording DrawTargets.
1420 * This is considered fallible, and replaying this without making the surface
1421 * available to the replay will just skip the draw.
1423 virtual void DrawDependentSurface(uint64_t aId, const Rect& aDest) {
1424 MOZ_CRASH("GFX: DrawDependentSurface");
1428 * Draw the output of a FilterNode to the DrawTarget.
1430 * @param aNode FilterNode to draw
1431 * @param aSourceRect Source rectangle in FilterNode space to draw
1432 * @param aDestPoint Destination point on the DrawTarget to draw the
1433 * SourceRectangle of the filter output to
1435 virtual void DrawFilter(FilterNode* aNode, const Rect& aSourceRect,
1436 const Point& aDestPoint,
1437 const DrawOptions& aOptions = DrawOptions()) = 0;
1440 * Blend a surface to the draw target with a shadow. The shadow is drawn as a
1441 * gaussian blur using a specified sigma. The shadow is clipped to the size
1442 * of the input surface, so the input surface should contain a transparent
1443 * border the size of the approximate coverage of the blur (3 * aSigma).
1444 * NOTE: This function works in device space!
1446 * @param aSurface Source surface to draw.
1447 * @param aDest Destination point that this drawing operation should draw to.
1448 * @param aShadow Description of shadow to be drawn.
1449 * @param aOperator Composition operator used
1451 virtual void DrawSurfaceWithShadow(SourceSurface* aSurface,
1452 const Point& aDest,
1453 const ShadowOptions& aShadow,
1454 CompositionOp aOperator) = 0;
1457 * Draws a shadow for the specified path, which may be optionally stroked.
1459 * @param aPath The path to use for the shadow geometry.
1460 * @param aPattern The pattern to use for filling the path.
1461 * @param aShadow Description of shadow to be drawn.
1462 * @param aOptions General drawing options to apply to drawing the path.
1463 * @param aStrokeOptions Stroking parameters that control stroking of path
1464 * geometry, if supplied.
1466 virtual void DrawShadow(const Path* aPath, const Pattern& aPattern,
1467 const ShadowOptions& aShadow,
1468 const DrawOptions& aOptions = DrawOptions(),
1469 const StrokeOptions* aStrokeOptions = nullptr);
1472 * Clear a rectangle on the draw target to transparent black. This will
1473 * respect the clipping region and transform.
1475 * @param aRect Rectangle to clear
1477 virtual void ClearRect(const Rect& aRect) = 0;
1480 * This is essentially a 'memcpy' between two surfaces. It moves a pixel
1481 * aligned area from the source surface unscaled directly onto the
1482 * drawtarget. This ignores both transform and clip.
1484 * @param aSurface Surface to copy from
1485 * @param aSourceRect Source rectangle to be copied
1486 * @param aDest Destination point to copy the surface to
1488 virtual void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect,
1489 const IntPoint& aDestination) = 0;
1491 /** @see CopySurface
1492 * Same as CopySurface, except uses itself as the source.
1494 * Some backends may be able to optimize this better
1495 * than just taking a snapshot and using CopySurface.
1497 virtual void CopyRect(const IntRect& aSourceRect,
1498 const IntPoint& aDestination) {
1499 RefPtr<SourceSurface> source = Snapshot();
1500 CopySurface(source, aSourceRect, aDestination);
1504 * Fill a rectangle on the DrawTarget with a certain source pattern.
1506 * @param aRect Rectangle that forms the mask of this filling operation
1507 * @param aPattern Pattern that forms the source of this filling operation
1508 * @param aOptions Options that are applied to this operation
1510 virtual void FillRect(const Rect& aRect, const Pattern& aPattern,
1511 const DrawOptions& aOptions = DrawOptions()) = 0;
1514 * Fill a rounded rectangle on the DrawTarget with a certain source pattern.
1516 * @param aRect Rounded rectangle that forms the mask of this filling
1517 * operation
1518 * @param aPattern Pattern that forms the source of this filling operation
1519 * @param aOptions Options that are applied to this operation
1521 virtual void FillRoundedRect(const RoundedRect& aRect,
1522 const Pattern& aPattern,
1523 const DrawOptions& aOptions = DrawOptions());
1526 * Stroke a rectangle on the DrawTarget with a certain source pattern.
1528 * @param aRect Rectangle that forms the mask of this stroking operation
1529 * @param aPattern Pattern that forms the source of this stroking operation
1530 * @param aOptions Options that are applied to this operation
1532 virtual void StrokeRect(const Rect& aRect, const Pattern& aPattern,
1533 const StrokeOptions& aStrokeOptions = StrokeOptions(),
1534 const DrawOptions& aOptions = DrawOptions()) = 0;
1537 * Stroke a line on the DrawTarget with a certain source pattern.
1539 * @param aStart Starting point of the line
1540 * @param aEnd End point of the line
1541 * @param aPattern Pattern that forms the source of this stroking operation
1542 * @param aOptions Options that are applied to this operation
1544 virtual void StrokeLine(const Point& aStart, const Point& aEnd,
1545 const Pattern& aPattern,
1546 const StrokeOptions& aStrokeOptions = StrokeOptions(),
1547 const DrawOptions& aOptions = DrawOptions()) = 0;
1550 * Stroke a circle on the DrawTarget with a certain source pattern.
1552 * @param aCircle the parameters of the circle
1553 * @param aPattern Pattern that forms the source of this stroking operation
1554 * @param aOptions Options that are applied to this operation
1556 virtual void StrokeCircle(
1557 const Point& aOrigin, float radius, const Pattern& aPattern,
1558 const StrokeOptions& aStrokeOptions = StrokeOptions(),
1559 const DrawOptions& aOptions = DrawOptions());
1562 * Stroke a path on the draw target with a certain source pattern.
1564 * @param aPath Path that is to be stroked
1565 * @param aPattern Pattern that should be used for the stroke
1566 * @param aStrokeOptions Stroke options used for this operation
1567 * @param aOptions Draw options used for this operation
1569 virtual void Stroke(const Path* aPath, const Pattern& aPattern,
1570 const StrokeOptions& aStrokeOptions = StrokeOptions(),
1571 const DrawOptions& aOptions = DrawOptions()) = 0;
1574 * Fill a path on the draw target with a certain source pattern.
1576 * @param aPath Path that is to be filled
1577 * @param aPattern Pattern that should be used for the fill
1578 * @param aOptions Draw options used for this operation
1580 virtual void Fill(const Path* aPath, const Pattern& aPattern,
1581 const DrawOptions& aOptions = DrawOptions()) = 0;
1584 * Fill a circle on the DrawTarget with a certain source pattern.
1586 * @param aCircle the parameters of the circle
1587 * @param aPattern Pattern that forms the source of this stroking operation
1588 * @param aOptions Options that are applied to this operation
1590 virtual void FillCircle(const Point& aOrigin, float radius,
1591 const Pattern& aPattern,
1592 const DrawOptions& aOptions = DrawOptions());
1595 * Fill a series of glyphs on the draw target with a certain source pattern.
1597 virtual void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
1598 const Pattern& aPattern,
1599 const DrawOptions& aOptions = DrawOptions()) = 0;
1602 * Stroke a series of glyphs on the draw target with a certain source pattern.
1604 virtual void StrokeGlyphs(
1605 ScaledFont* aFont, const GlyphBuffer& aBuffer, const Pattern& aPattern,
1606 const StrokeOptions& aStrokeOptions = StrokeOptions(),
1607 const DrawOptions& aOptions = DrawOptions());
1610 * This takes a source pattern and a mask, and composites the source pattern
1611 * onto the destination surface using the alpha channel of the mask pattern
1612 * as a mask for the operation.
1614 * @param aSource Source pattern
1615 * @param aMask Mask pattern
1616 * @param aOptions Drawing options
1618 virtual void Mask(const Pattern& aSource, const Pattern& aMask,
1619 const DrawOptions& aOptions = DrawOptions()) = 0;
1622 * This takes a source pattern and a mask, and composites the source pattern
1623 * onto the destination surface using the alpha channel of the mask source.
1624 * The operation is bound by the extents of the mask.
1626 * @param aSource Source pattern
1627 * @param aMask Mask surface
1628 * @param aOffset a transformed offset that the surface is masked at
1629 * @param aOptions Drawing options
1631 virtual void MaskSurface(const Pattern& aSource, SourceSurface* aMask,
1632 Point aOffset,
1633 const DrawOptions& aOptions = DrawOptions()) = 0;
1636 * Draw aSurface using the 3D transform aMatrix. The DrawTarget's transform
1637 * and clip are applied after the 3D transform.
1639 * If the transform fails (i.e. because aMatrix is singular), false is
1640 * returned and nothing is drawn.
1642 virtual bool Draw3DTransformedSurface(SourceSurface* aSurface,
1643 const Matrix4x4& aMatrix);
1646 * Push a clip to the DrawTarget.
1648 * @param aPath The path to clip to
1650 virtual void PushClip(const Path* aPath) = 0;
1653 * Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
1654 * is specified in user space.
1656 * @param aRect The rect to clip to
1658 virtual void PushClipRect(const Rect& aRect) = 0;
1661 * Push a clip region specifed by the union of axis-aligned rectangular
1662 * clips to the DrawTarget. These rectangles are specified in device space.
1663 * This must be balanced by a corresponding call to PopClip within a layer.
1665 * @param aRects The rects to clip to
1666 * @param aCount The number of rectangles
1668 virtual void PushDeviceSpaceClipRects(const IntRect* aRects, uint32_t aCount);
1670 /** Pop a clip from the DrawTarget. A pop without a corresponding push will
1671 * be ignored.
1673 virtual void PopClip() = 0;
1676 * Push a 'layer' to the DrawTarget, a layer is a temporary surface that all
1677 * drawing will be redirected to, this is used for example to support group
1678 * opacity or the masking of groups. Clips must be balanced within a layer,
1679 * i.e. between a matching PushLayer/PopLayer pair there must be as many
1680 * PushClip(Rect) calls as there are PopClip calls.
1682 * @param aOpaque Whether the layer will be opaque
1683 * @param aOpacity Opacity of the layer
1684 * @param aMask Mask applied to the layer
1685 * @param aMaskTransform Transform applied to the layer mask
1686 * @param aBounds Optional bounds in device space to which the layer is
1687 * limited in size.
1688 * @param aCopyBackground Whether to copy the background into the layer, this
1689 * is only supported when aOpaque is true.
1691 virtual void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
1692 const Matrix& aMaskTransform,
1693 const IntRect& aBounds = IntRect(),
1694 bool aCopyBackground = false) {
1695 MOZ_CRASH("GFX: PushLayer");
1699 * Push a 'layer' to the DrawTarget, a layer is a temporary surface that all
1700 * drawing will be redirected to, this is used for example to support group
1701 * opacity or the masking of groups. Clips must be balanced within a layer,
1702 * i.e. between a matching PushLayer/PopLayer pair there must be as many
1703 * PushClip(Rect) calls as there are PopClip calls.
1705 * @param aOpaque Whether the layer will be opaque
1706 * @param aOpacity Opacity of the layer
1707 * @param aMask Mask applied to the layer
1708 * @param aMaskTransform Transform applied to the layer mask
1709 * @param aBounds Optional bounds in device space to which the layer is
1710 * limited in size.
1711 * @param aCopyBackground Whether to copy the background into the layer, this
1712 * is only supported when aOpaque is true.
1714 virtual void PushLayerWithBlend(bool aOpaque, Float aOpacity,
1715 SourceSurface* aMask,
1716 const Matrix& aMaskTransform,
1717 const IntRect& aBounds = IntRect(),
1718 bool aCopyBackground = false,
1719 CompositionOp = CompositionOp::OP_OVER) {
1720 MOZ_CRASH("GFX: PushLayerWithBlend");
1724 * This balances a call to PushLayer and proceeds to blend the layer back
1725 * onto the background. This blend will blend the temporary surface back
1726 * onto the target in device space using POINT sampling and operator over.
1728 virtual void PopLayer() { MOZ_CRASH("GFX: PopLayer"); }
1731 * Perform an in-place blur operation. This is only supported on data draw
1732 * targets.
1734 virtual void Blur(const AlphaBoxBlur& aBlur);
1737 * Performs an in-place edge padding operation.
1738 * aRegion is specified in device space.
1740 virtual void PadEdges(const IntRegion& aRegion);
1743 * Performs an in-place buffer unrotation operation.
1745 virtual bool Unrotate(IntPoint aRotation);
1748 * Create a SourceSurface optimized for use with this DrawTarget from
1749 * existing bitmap data in memory.
1751 * The SourceSurface does not take ownership of aData, and may be freed at any
1752 * time.
1754 virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(
1755 unsigned char* aData, const IntSize& aSize, int32_t aStride,
1756 SurfaceFormat aFormat) const = 0;
1759 * Create a SourceSurface optimized for use with this DrawTarget from an
1760 * arbitrary SourceSurface type supported by this backend. This may return
1761 * aSourceSurface or some other existing surface.
1763 virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(
1764 SourceSurface* aSurface) const = 0;
1765 virtual already_AddRefed<SourceSurface> OptimizeSourceSurfaceForUnknownAlpha(
1766 SourceSurface* aSurface) const {
1767 return OptimizeSourceSurface(aSurface);
1771 * Create a SourceSurface for a type of NativeSurface. This may fail if the
1772 * draw target does not know how to deal with the type of NativeSurface passed
1773 * in. If this succeeds, the SourceSurface takes the ownersip of the
1774 * NativeSurface.
1776 virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(
1777 const NativeSurface& aSurface) const = 0;
1780 * Create a DrawTarget whose snapshot is optimized for use with this
1781 * DrawTarget.
1783 virtual already_AddRefed<DrawTarget> CreateSimilarDrawTarget(
1784 const IntSize& aSize, SurfaceFormat aFormat) const = 0;
1787 * Create a DrawTarget whose backing surface is optimized for use with this
1788 * DrawTarget.
1790 virtual already_AddRefed<DrawTarget> CreateSimilarDrawTargetWithBacking(
1791 const IntSize& aSize, SurfaceFormat aFormat) const {
1792 return CreateSimilarDrawTarget(aSize, aFormat);
1796 * Create a DrawTarget whose snapshot is optimized for use with this
1797 * DrawTarget and aFilter.
1798 * @param aSource is the FilterNode that that will be attached to this
1799 * surface.
1800 * @param aSourceRect is the source rect that will be passed to DrawFilter
1801 * @param aDestPoint is the dest point that will be passed to DrawFilter.
1803 virtual already_AddRefed<DrawTarget> CreateSimilarDrawTargetForFilter(
1804 const IntSize& aSize, SurfaceFormat aFormat, FilterNode* aFilter,
1805 FilterNode* aSource, const Rect& aSourceRect, const Point& aDestPoint) {
1806 return CreateSimilarDrawTarget(aSize, aFormat);
1810 * Returns false if CreateSimilarDrawTarget would return null with the same
1811 * parameters. May return true even in cases where CreateSimilarDrawTarget
1812 * return null (i.e. this function returning false has meaning, but returning
1813 * true doesn't guarantee anything).
1815 virtual bool CanCreateSimilarDrawTarget(const IntSize& aSize,
1816 SurfaceFormat aFormat) const {
1817 return true;
1821 * Create a draw target optimized for drawing a shadow.
1823 * Note that aSigma is the blur radius that must be used when we draw the
1824 * shadow. Also note that this doesn't affect the size of the allocated
1825 * surface, the caller is still responsible for including the shadow area in
1826 * its size.
1828 virtual already_AddRefed<DrawTarget> CreateShadowDrawTarget(
1829 const IntSize& aSize, SurfaceFormat aFormat, float aSigma) const {
1830 return CreateSimilarDrawTarget(aSize, aFormat);
1834 * Create a similar DrawTarget in the same space as this DrawTarget whose
1835 * device size may be clipped based on the active clips intersected with
1836 * aBounds (if it is not empty).
1837 * aRect is a rectangle in user space.
1839 virtual RefPtr<DrawTarget> CreateClippedDrawTarget(const Rect& aBounds,
1840 SurfaceFormat aFormat) = 0;
1843 * Create a similar draw target, but if the draw target is not backed by a
1844 * raster backend (for example, it is capturing or recording), force it to
1845 * create a raster target instead. This is intended for code that wants to
1846 * cache pixels, and would have no effect if it were caching a recording.
1848 virtual RefPtr<DrawTarget> CreateSimilarRasterTarget(
1849 const IntSize& aSize, SurfaceFormat aFormat) const {
1850 return CreateSimilarDrawTarget(aSize, aFormat);
1854 * Create a path builder with the specified fillmode.
1856 * We need the fill mode up front because of Direct2D.
1857 * ID2D1SimplifiedGeometrySink requires the fill mode
1858 * to be set before calling BeginFigure().
1860 virtual already_AddRefed<PathBuilder> CreatePathBuilder(
1861 FillRule aFillRule = FillRule::FILL_WINDING) const = 0;
1864 * Create a GradientStops object that holds information about a set of
1865 * gradient stops, this object is required for linear or radial gradient
1866 * patterns to represent the color stops in the gradient.
1868 * @param aStops An array of gradient stops
1869 * @param aNumStops Number of stops in the array aStops
1870 * @param aExtendNone This describes how to extend the stop color outside of
1871 * the gradient area.
1873 virtual already_AddRefed<GradientStops> CreateGradientStops(
1874 GradientStop* aStops, uint32_t aNumStops,
1875 ExtendMode aExtendMode = ExtendMode::CLAMP) const = 0;
1878 * Create a FilterNode object that can be used to apply a filter to various
1879 * inputs.
1881 * @param aType Type of filter node to be created.
1883 virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) = 0;
1885 Matrix GetTransform() const { return mTransform; }
1888 * Set a transform on the surface, this transform is applied at drawing time
1889 * to both the mask and source of the operation.
1891 * Performance note: For some backends it is expensive to change the current
1892 * transform (because transforms affect a lot of the parts of the pipeline,
1893 * so new transform change can result in a pipeline flush). To get around
1894 * this, DrawTarget implementations buffer transform changes and try to only
1895 * set the current transform on the backend when required. That tracking has
1896 * its own performance impact though, and ideally callers would be smart
1897 * enough not to require it. At a future date this method may stop this
1898 * doing transform buffering so, if you're a consumer, please try to be smart
1899 * about calling this method as little as possible. For example, instead of
1900 * concatenating a translation onto the current transform then calling
1901 * FillRect, try to integrate the translation into FillRect's aRect
1902 * argument's x/y offset.
1904 virtual void SetTransform(const Matrix& aTransform) {
1905 mTransform = aTransform;
1906 mTransformDirty = true;
1909 inline void ConcatTransform(const Matrix& aTransform) {
1910 SetTransform(aTransform * Matrix(GetTransform()));
1913 SurfaceFormat GetFormat() const { return mFormat; }
1915 /** Tries to get a native surface for a DrawTarget, this may fail if the
1916 * draw target cannot convert to this surface type.
1918 virtual void* GetNativeSurface(NativeSurfaceType aType) { return nullptr; }
1920 virtual bool IsTiledDrawTarget() const { return false; }
1921 virtual bool SupportsRegionClipping() const { return true; }
1923 void AddUserData(UserDataKey* key, void* userData, void (*destroy)(void*)) {
1924 mUserData.Add(key, userData, destroy);
1926 void* GetUserData(UserDataKey* key) const { return mUserData.Get(key); }
1927 void* RemoveUserData(UserDataKey* key) { return mUserData.Remove(key); }
1929 /** Within this rectangle all pixels will be opaque by the time the result of
1930 * this DrawTarget is first used for drawing. Either by the underlying surface
1931 * being used as an input to external drawing, or Snapshot() being called.
1932 * This rectangle is specified in device space.
1934 void SetOpaqueRect(const IntRect& aRect) { mOpaqueRect = aRect; }
1936 const IntRect& GetOpaqueRect() const { return mOpaqueRect; }
1938 virtual bool IsCurrentGroupOpaque() {
1939 return GetFormat() == SurfaceFormat::B8G8R8X8;
1942 virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) {
1943 mPermitSubpixelAA = aPermitSubpixelAA;
1946 bool GetPermitSubpixelAA() { return mPermitSubpixelAA; }
1949 * Mark the end of an Item in a DrawTargetRecording. These markers
1950 * are used for merging recordings together.
1952 * This should only be called on the 'root' DrawTargetRecording.
1953 * Calling it on a child DrawTargetRecordings will cause confusion.
1955 * Note: this is a bit of a hack. It might be better to just recreate
1956 * the DrawTargetRecording.
1958 virtual void FlushItem(const IntRect& aBounds) {}
1961 * Ensures that no snapshot is still pointing to this DrawTarget's surface
1962 * data.
1964 * This can be useful if the DrawTarget is wrapped around data that it does
1965 * not own, and for some reason the owner of the data has to make it
1966 * temporarily unavailable without the DrawTarget knowing about it. This can
1967 * cause costly surface copies, so it should not be used without a a good
1968 * reason.
1970 virtual void DetachAllSnapshots() = 0;
1973 * Remove all clips in the DrawTarget.
1975 virtual bool RemoveAllClips() { return false; }
1977 protected:
1978 UserData mUserData;
1979 Matrix mTransform;
1980 IntRect mOpaqueRect;
1981 bool mTransformDirty : 1;
1982 bool mPermitSubpixelAA : 1;
1984 SurfaceFormat mFormat;
1987 class DrawEventRecorder : public RefCounted<DrawEventRecorder> {
1988 public:
1989 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorder)
1990 // returns true if there were any items in the recording
1991 virtual bool Finish() = 0;
1992 virtual ~DrawEventRecorder() = default;
1995 struct Tile {
1996 RefPtr<DrawTarget> mDrawTarget;
1997 IntPoint mTileOrigin;
2000 struct TileSet {
2001 Tile* mTiles;
2002 size_t mTileCount;
2005 struct Config {
2006 LogForwarder* mLogForwarder;
2007 int32_t mMaxTextureSize;
2008 int32_t mMaxAllocSize;
2010 Config()
2011 : mLogForwarder(nullptr),
2012 mMaxTextureSize(kReasonableSurfaceSize),
2013 mMaxAllocSize(52000000) {}
2016 class GFX2D_API Factory {
2017 using char_type = filesystem::Path::value_type;
2019 public:
2020 static void Init(const Config& aConfig);
2021 static void ShutDown();
2023 static bool HasSSE2();
2024 static bool HasSSE4();
2027 * Returns false if any of the following are true:
2029 * - the width/height of |sz| are less than or equal to zero
2030 * - the width/height of |sz| are greater than |limit|
2031 * - the number of bytes that need to be allocated for the surface is too
2032 * big to fit in an int32_t, or bigger than |allocLimit|, if specifed
2034 * To calculate the number of bytes that need to be allocated for the surface
2035 * this function makes the conservative assumption that there need to be
2036 * 4 bytes-per-pixel, and the stride alignment is 16 bytes.
2038 * The reason for using int32_t rather than uint32_t is again to be
2039 * conservative; some code has in the past and may in the future use signed
2040 * integers to store buffer lengths etc.
2042 static bool CheckSurfaceSize(const IntSize& sz, int32_t limit = 0,
2043 int32_t allocLimit = 0);
2045 /** Make sure the given dimension satisfies the CheckSurfaceSize and is
2046 * within 8k limit. The 8k value is chosen a bit randomly.
2048 static bool ReasonableSurfaceSize(const IntSize& aSize);
2050 static bool AllowedSurfaceSize(const IntSize& aSize);
2052 static already_AddRefed<DrawTarget> CreateDrawTargetForCairoSurface(
2053 cairo_surface_t* aSurface, const IntSize& aSize,
2054 SurfaceFormat* aFormat = nullptr);
2056 static already_AddRefed<SourceSurface> CreateSourceSurfaceForCairoSurface(
2057 cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat aFormat);
2059 static already_AddRefed<DrawTarget> CreateDrawTarget(BackendType aBackend,
2060 const IntSize& aSize,
2061 SurfaceFormat aFormat);
2063 static already_AddRefed<PathBuilder> CreatePathBuilder(
2064 BackendType aBackend, FillRule aFillRule = FillRule::FILL_WINDING);
2067 * Create a simple PathBuilder, which uses SKIA backend.
2069 static already_AddRefed<PathBuilder> CreateSimplePathBuilder();
2071 static already_AddRefed<DrawTarget> CreateRecordingDrawTarget(
2072 DrawEventRecorder* aRecorder, DrawTarget* aDT, IntRect aRect);
2074 static already_AddRefed<DrawTarget> CreateDrawTargetForData(
2075 BackendType aBackend, unsigned char* aData, const IntSize& aSize,
2076 int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
2078 #ifdef XP_DARWIN
2079 static already_AddRefed<ScaledFont> CreateScaledFontForMacFont(
2080 CGFontRef aCGFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
2081 bool aUseFontSmoothing = true, bool aApplySyntheticBold = false,
2082 bool aHasColorGlyphs = false);
2083 #endif
2085 #ifdef MOZ_WIDGET_GTK
2086 static already_AddRefed<ScaledFont> CreateScaledFontForFontconfigFont(
2087 const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
2088 RefPtr<SharedFTFace> aFace, FcPattern* aPattern);
2089 #endif
2091 #ifdef MOZ_WIDGET_ANDROID
2092 static already_AddRefed<ScaledFont> CreateScaledFontForFreeTypeFont(
2093 const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
2094 RefPtr<SharedFTFace> aFace, bool aApplySyntheticBold = false);
2095 #endif
2098 * This creates a NativeFontResource from TrueType data.
2100 * @param aData Pointer to the data
2101 * @param aSize Size of the TrueType data
2102 * @param aFontType Type of NativeFontResource that should be created.
2103 * @param aFontContext Optional native font context to be used to create the
2104 * NativeFontResource.
2105 * @return a NativeFontResource of nullptr if failed.
2107 static already_AddRefed<NativeFontResource> CreateNativeFontResource(
2108 uint8_t* aData, uint32_t aSize, FontType aFontType,
2109 void* aFontContext = nullptr);
2112 * This creates an unscaled font of the given type based on font descriptor
2113 * data retrieved from ScaledFont::GetFontDescriptor.
2115 static already_AddRefed<UnscaledFont> CreateUnscaledFontFromFontDescriptor(
2116 FontType aType, const uint8_t* aData, uint32_t aDataLength,
2117 uint32_t aIndex);
2120 * This creates a simple data source surface for a certain size. It allocates
2121 * new memory for the surface. This memory is freed when the surface is
2122 * destroyed. The caller is responsible for handing the case where nullptr
2123 * is returned. The surface is not zeroed unless requested.
2125 static already_AddRefed<DataSourceSurface> CreateDataSourceSurface(
2126 const IntSize& aSize, SurfaceFormat aFormat, bool aZero = false);
2129 * This creates a simple data source surface for a certain size with a
2130 * specific stride, which must be large enough to fit all pixels.
2131 * It allocates new memory for the surface. This memory is freed when
2132 * the surface is destroyed. The caller is responsible for handling the case
2133 * where nullptr is returned. The surface is not zeroed unless requested.
2135 static already_AddRefed<DataSourceSurface> CreateDataSourceSurfaceWithStride(
2136 const IntSize& aSize, SurfaceFormat aFormat, int32_t aStride,
2137 bool aZero = false);
2139 typedef void (*SourceSurfaceDeallocator)(void* aClosure);
2142 * This creates a simple data source surface for some existing data. It will
2143 * wrap this data and the data for this source surface.
2145 * We can provide a custom destroying function for |aData|. This will be
2146 * called in the surface dtor using |aDeallocator| and the |aClosure|. If
2147 * there are errors during construction(return a nullptr surface), the caller
2148 * is responsible for the deallocation.
2150 * If there is no destroying function, the caller is responsible for
2151 * deallocating the aData memory only after destruction of this
2152 * DataSourceSurface.
2154 static already_AddRefed<DataSourceSurface> CreateWrappingDataSourceSurface(
2155 uint8_t* aData, int32_t aStride, const IntSize& aSize,
2156 SurfaceFormat aFormat, SourceSurfaceDeallocator aDeallocator = nullptr,
2157 void* aClosure = nullptr);
2159 static void CopyDataSourceSurface(DataSourceSurface* aSource,
2160 DataSourceSurface* aDest);
2162 static uint32_t GetMaxSurfaceSize(BackendType aType);
2164 static LogForwarder* GetLogForwarder() {
2165 return sConfig ? sConfig->mLogForwarder : nullptr;
2168 private:
2169 static Config* sConfig;
2171 public:
2172 static void PurgeAllCaches();
2174 static already_AddRefed<DrawTarget> CreateOffsetDrawTarget(
2175 DrawTarget* aDrawTarget, IntPoint aTileOrigin);
2177 static bool DoesBackendSupportDataDrawtarget(BackendType aType);
2179 static void SetBGRSubpixelOrder(bool aBGR);
2180 static bool GetBGRSubpixelOrder();
2182 private:
2183 static bool mBGRSubpixelOrder;
2185 public:
2186 static already_AddRefed<DrawTarget> CreateDrawTargetWithSkCanvas(
2187 SkCanvas* aCanvas);
2189 #ifdef MOZ_ENABLE_FREETYPE
2190 static void SetFTLibrary(FT_Library aFTLibrary);
2191 static FT_Library GetFTLibrary();
2193 static FT_Library NewFTLibrary();
2194 static void ReleaseFTLibrary(FT_Library aFTLibrary);
2195 static void LockFTLibrary(FT_Library aFTLibrary);
2196 static void UnlockFTLibrary(FT_Library aFTLibrary);
2198 static FT_Face NewFTFace(FT_Library aFTLibrary, const char* aFileName,
2199 int aFaceIndex);
2200 static already_AddRefed<SharedFTFace> NewSharedFTFace(FT_Library aFTLibrary,
2201 const char* aFilename,
2202 int aFaceIndex);
2203 static FT_Face NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData,
2204 size_t aDataSize, int aFaceIndex);
2205 static already_AddRefed<SharedFTFace> NewSharedFTFaceFromData(
2206 FT_Library aFTLibrary, const uint8_t* aData, size_t aDataSize,
2207 int aFaceIndex, SharedFTFaceData* aSharedData = nullptr);
2208 static void ReleaseFTFace(FT_Face aFace);
2209 static FT_Error LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex,
2210 int32_t aFlags);
2212 private:
2213 static FT_Library mFTLibrary;
2214 static StaticMutex mFTLock;
2216 public:
2217 #endif
2219 #ifdef WIN32
2220 static already_AddRefed<DrawTarget> CreateDrawTargetForD3D11Texture(
2221 ID3D11Texture2D* aTexture, SurfaceFormat aFormat);
2224 * Attempts to create and install a D2D1 device from the supplied Direct3D11
2225 * device. Returns true on success, or false on failure and leaves the
2226 * D2D1/Direct3D11 devices unset.
2228 static bool SetDirect3D11Device(ID3D11Device* aDevice);
2229 static RefPtr<ID3D11Device> GetDirect3D11Device();
2230 static RefPtr<ID2D1Device> GetD2D1Device(uint32_t* aOutSeqNo = nullptr);
2231 static bool HasD2D1Device();
2232 static RefPtr<IDWriteFactory> GetDWriteFactory();
2233 static RefPtr<IDWriteFactory> EnsureDWriteFactory();
2234 static bool SupportsD2D1();
2235 static RefPtr<IDWriteFontCollection> GetDWriteSystemFonts(
2236 bool aUpdate = false);
2237 static RefPtr<ID2D1DeviceContext> GetD2DDeviceContext();
2239 static uint64_t GetD2DVRAMUsageDrawTarget();
2240 static uint64_t GetD2DVRAMUsageSourceSurface();
2241 static void D2DCleanup();
2243 static already_AddRefed<ScaledFont> CreateScaledFontForDWriteFont(
2244 IDWriteFontFace* aFontFace, const gfxFontStyle* aStyle,
2245 const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
2246 bool aUseEmbeddedBitmap, bool aUseMultistrikeBold, bool aGDIForced);
2248 static already_AddRefed<ScaledFont> CreateScaledFontForGDIFont(
2249 const void* aLogFont, const RefPtr<UnscaledFont>& aUnscaledFont,
2250 Float aSize);
2252 static void SetSystemTextQuality(uint8_t aQuality);
2254 static already_AddRefed<DataSourceSurface>
2255 CreateBGRA8DataSourceSurfaceForD3D11Texture(ID3D11Texture2D* aSrcTexture,
2256 uint32_t aArrayIndex = 0);
2258 static bool ReadbackTexture(layers::TextureData* aDestCpuTexture,
2259 ID3D11Texture2D* aSrcTexture);
2261 static bool ReadbackTexture(DataSourceSurface* aDestCpuTexture,
2262 ID3D11Texture2D* aSrcTexture,
2263 uint32_t aArrayIndex = 0);
2265 private:
2266 static StaticRefPtr<ID2D1Device> mD2D1Device;
2267 static StaticRefPtr<ID3D11Device> mD3D11Device;
2268 static StaticRefPtr<IDWriteFactory> mDWriteFactory;
2269 static bool mDWriteFactoryInitialized;
2270 static StaticRefPtr<IDWriteFontCollection> mDWriteSystemFonts;
2271 static StaticRefPtr<ID2D1DeviceContext> mMTDC;
2272 static StaticRefPtr<ID2D1DeviceContext> mOffMTDC;
2274 static bool ReadbackTexture(uint8_t* aDestData, int32_t aDestStride,
2275 ID3D11Texture2D* aSrcTexture);
2277 // DestTextureT can be TextureData or DataSourceSurface.
2278 template <typename DestTextureT>
2279 static bool ConvertSourceAndRetryReadback(DestTextureT* aDestCpuTexture,
2280 ID3D11Texture2D* aSrcTexture,
2281 uint32_t aArrayIndex = 0);
2283 protected:
2284 // This guards access to the singleton devices above, as well as the
2285 // singleton devices in DrawTargetD2D1.
2286 static StaticMutex mDeviceLock;
2287 // This synchronizes access between different D2D drawtargets and their
2288 // implied dependency graph.
2289 static StaticMutex mDTDependencyLock;
2291 friend class DrawTargetD2D1;
2292 #endif // WIN32
2295 class MOZ_RAII AutoSerializeWithMoz2D final {
2296 public:
2297 explicit AutoSerializeWithMoz2D(BackendType aBackendType);
2298 ~AutoSerializeWithMoz2D();
2300 private:
2301 #if defined(WIN32)
2302 RefPtr<ID2D1Multithread> mMT;
2303 #endif
2306 } // namespace gfx
2307 } // namespace mozilla
2309 #endif // _MOZILLA_GFX_2D_H