Bug 1876335 - use GRADLE_MAVEN_REPOSITORIES in more places. r=owlish,geckoview-review...
[gecko.git] / gfx / 2d / 2D.h
blobe6b94f86eae7b3d940629026fcc04f719e1c654b
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 <functional>
18 #include <vector>
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
30 // solution.
31 #include "mozilla/RefPtr.h"
32 #include "mozilla/StaticMutex.h"
33 #include "mozilla/StaticPtr.h"
34 #include "mozilla/ThreadSafeWeakPtr.h"
35 #include "mozilla/Atomics.h"
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
44 # endif
45 #endif
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;
56 struct FT_FaceRec_;
57 typedef FT_FaceRec_* FT_Face;
59 typedef int FT_Error;
61 struct _FcPattern;
62 typedef _FcPattern FcPattern;
64 struct ID3D11Texture2D;
65 struct ID3D11Device;
66 struct ID2D1Device;
67 struct ID2D1DeviceContext;
68 struct ID2D1Multithread;
69 struct IDWriteFactory;
70 struct IDWriteRenderingParams;
71 struct IDWriteFontFace;
72 struct IDWriteFontCollection;
74 class SkCanvas;
75 struct gfxFontStyle;
77 struct CGContext;
78 typedef struct CGContext* CGContextRef;
80 struct CGFont;
81 typedef CGFont* CGFontRef;
83 namespace mozilla {
85 class Mutex;
87 namespace layers {
88 class MemoryOrShmem;
89 class SurfaceDescriptorBuffer;
90 class TextureData;
91 } // namespace layers
93 namespace wr {
94 struct FontInstanceOptions;
95 struct FontInstancePlatformOptions;
96 } // namespace wr
98 namespace gfx {
99 class UnscaledFont;
100 class ScaledFont;
101 } // namespace gfx
103 namespace gfx {
105 class AlphaBoxBlur;
106 class ScaledFont;
107 class SourceSurface;
108 class DataSourceSurface;
109 class DrawTarget;
110 class DrawEventRecorder;
111 class FilterNode;
112 class LogForwarder;
114 struct NativeSurface {
115 NativeSurfaceType mType;
116 SurfaceFormat mFormat;
117 gfx::IntSize mSize;
118 void* mSurface;
122 * This structure is used to send draw options that are universal to all drawing
123 * operations.
125 struct DrawOptions {
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)
130 : mAlpha(aAlpha),
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
139 operation. */
142 struct StoredStrokeOptions;
145 * This structure is used to send stroke options that are used in stroking
146 * operations.
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),
161 mLineCap(aLineCap) {
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
173 stroking begins. */
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) {
198 if (mDashLength) {
199 Float* pattern = new Float[mDashLength];
200 memcpy(pattern, mDashPattern, mDashLength * sizeof(Float));
201 mDashPattern = pattern;
205 ~StoredStrokeOptions() {
206 if (mDashPattern) {
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) {}
226 SamplingFilter
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,
241 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
255 * fail.
257 class GradientStops : public SupportsThreadSafeWeakPtr<GradientStops> {
258 public:
259 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops)
260 virtual ~GradientStops() = default;
262 virtual BackendType GetBackendType() const = 0;
263 virtual bool IsValid() const { return true; }
265 protected:
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.
275 class Pattern {
276 public:
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); }
296 protected:
297 Pattern() = default;
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.
303 return true;
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 {
314 public:
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) {
325 return false;
327 const ColorPattern& other = static_cast<const ColorPattern&>(aOther);
328 return mColor == other.mColor;
331 DeviceColor 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;
343 public:
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())
348 : mBegin(aBegin),
349 mEnd(aEnd),
350 mStops(std::move(aStops)),
351 mMatrix(aMatrix) {}
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) {
373 return false;
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
388 user space */
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;
402 public:
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),
409 mCenter2(aCenter2),
410 mRadius1(aRadius1),
411 mRadius2(aRadius2),
412 mStops(std::move(aStops)),
413 mMatrix(aMatrix) {}
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),
419 mMatrix);
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) {
437 return false;
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;
465 public:
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())
470 : mCenter(aCenter),
471 mAngle(aAngle),
472 mStartOffset(aStartOffset),
473 mEndOffset(aEndOffset),
474 mStops(std::move(aStops)),
475 mMatrix(aMatrix) {}
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) {
500 return false;
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;
527 public:
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),
536 mMatrix(aMatrix),
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,
543 mSamplingRect);
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) {
562 return false;
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 */
572 SamplingFilter
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
578 specified. */
581 typedef SurfacePatternT<> SurfacePattern;
583 class StoredPattern;
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> {
598 public:
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.
612 struct SizeOfInfo {
613 SizeOfInfo()
614 : mHeapBytes(0),
615 mNonHeapBytes(0),
616 mUnknownBytes(0),
617 mExternalHandles(0),
618 mExternalId(0),
619 mTypes(0) {}
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
657 * created.
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 {
676 switch (GetType()) {
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:
685 return true;
686 default:
687 return false;
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) {
718 return nullptr;
721 protected:
722 friend class StoredPattern;
724 ThreadSafeUserData mUserData;
727 class DataSourceSurface : public SourceSurface {
728 public:
729 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurface, override)
730 DataSourceSurface() : mMapCount(0) {}
732 #ifdef DEBUG
733 virtual ~DataSourceSurface() { MOZ_ASSERT(mMapCount == 0); }
734 #endif
736 struct MappedSurface {
737 uint8_t* mData = nullptr;
738 int32_t mStride = 0;
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
746 * surfaces.
748 * Use IsMapped() to verify whether Map() succeeded or not.
750 class ScopedMap final {
751 public:
752 ScopedMap(DataSourceSurface* aSurface, MapType aType)
753 : mSurface(aSurface), mIsMapped(aSurface->Map(aType, &mMap)) {}
755 ScopedMap(ScopedMap&& aOther)
756 : mSurface(std::move(aOther.mSurface)),
757 mMap(aOther.mMap),
758 mIsMapped(aOther.mIsMapped) {
759 aOther.mMap.mData = nullptr;
760 aOther.mIsMapped = false;
763 ScopedMap& operator=(ScopedMap&& aOther) {
764 if (mIsMapped) {
765 mSurface->Unmap();
767 mSurface = std::move(aOther.mSurface);
768 mMap = aOther.mMap;
769 mIsMapped = aOther.mIsMapped;
770 aOther.mMap.mData = nullptr;
771 aOther.mIsMapped = false;
772 return *this;
775 ~ScopedMap() {
776 if (mIsMapped) {
777 mSurface->Unmap();
781 uint8_t* GetData() const {
782 MOZ_ASSERT(mIsMapped);
783 return mMap.mData;
786 int32_t GetStride() const {
787 MOZ_ASSERT(mIsMapped);
788 return mMap.mStride;
791 const MappedSurface* GetMappedSurface() const {
792 MOZ_ASSERT(mIsMapped);
793 return &mMap;
796 const DataSourceSurface* GetSurface() const {
797 MOZ_ASSERT(mIsMapped);
798 return mSurface;
801 bool IsMapped() const { return mIsMapped; }
803 private:
804 ScopedMap(const ScopedMap& aOther) = delete;
805 ScopedMap& operator=(const ScopedMap& aOther) = delete;
807 RefPtr<DataSourceSurface> mSurface;
808 MappedSurface mMap;
809 bool mIsMapped;
812 SurfaceType GetType() const override { return SurfaceType::DATA; }
813 /** @deprecated
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;
822 /** @deprecated
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;
845 if (success) {
846 mMapCount++;
848 return success;
851 virtual void Unmap() {
852 mMapCount--;
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) {}
881 protected:
882 Atomic<int32_t> mMapCount;
885 /** This is an abstract object that accepts path segments. */
886 class PathSink : public RefCounted<PathSink> {
887 public:
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; }
919 protected:
920 /** Point the current subpath is at - or where the next subpath will start
921 * if there is no active subpath.
923 Point mCurrentPoint;
925 /** Position of the previous MoveTo operation. */
926 Point mBeginPoint;
929 class PathBuilder;
930 class FlattenedPath;
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> {
936 public:
937 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(Path)
938 virtual ~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
962 * aPoint is given.
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,
972 const Point& aPoint,
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
984 * the transform.
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
1003 * mutable.
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;
1015 protected:
1016 Path();
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 {
1026 public:
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;
1038 struct Glyph {
1039 uint32_t mIndex;
1040 Point mPosition;
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 {
1052 const Glyph*
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
1058 class SharedFTFace;
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 {
1065 public:
1066 /** Utility for creating a new face from this data. */
1067 virtual already_AddRefed<SharedFTFace> CloneFace(int aFaceIndex = 0) {
1068 return nullptr;
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
1079 template <class T>
1080 class SharedFTFaceRefCountedData : public SharedFTFaceData {
1081 public:
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> {
1096 public:
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;
1108 private:
1109 ~FTUserFontData() {
1110 if (mFontData) {
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> {
1128 public:
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) {
1146 mLock.Lock();
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) {
1155 if (aOwner) {
1156 mLastLockOwner.compareExchange(aOwner, nullptr);
1160 private:
1161 FT_Face mFace;
1162 SharedFTFaceData* mData;
1163 Mutex mLock;
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;
1169 #endif
1171 class UnscaledFont : public SupportsThreadSafeWeakPtr<UnscaledFont> {
1172 public:
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,
1184 void* aBaton);
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*) {
1191 return false;
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) {
1200 return nullptr;
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,
1208 aNumVariations);
1211 protected:
1212 UnscaledFont() = default;
1214 private:
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> {
1223 public:
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
1237 * passed in.
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
1245 * others.
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*) {
1256 return false;
1259 virtual bool GetWRFontInstanceOptions(
1260 Maybe<wr::FontInstanceOptions>* aOutOptions,
1261 Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
1262 std::vector<FontVariation>* aOutVariations) {
1263 return false;
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;
1290 protected:
1291 explicit ScaledFont(const RefPtr<UnscaledFont>& aUnscaledFont)
1292 : mUnscaledFont(aUnscaledFont), mSyntheticObliqueAngle(0.0f) {}
1294 ThreadSafeUserData mUserData;
1295 RefPtr<UnscaledFont> mUnscaledFont;
1296 Float mSyntheticObliqueAngle;
1298 private:
1299 static Atomic<uint32_t> sDeletionCounter;
1303 * Derived classes hold a native font resource from which to create
1304 * ScaledFonts.
1306 class NativeFontResource
1307 : public external::AtomicRefCounted<NativeFontResource> {
1308 public:
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
1316 * data.
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();
1329 private:
1330 size_t mDataLength;
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> {
1339 public:
1340 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget)
1341 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
1371 * called.
1373 virtual already_AddRefed<SourceSurface> GetBackingSurface() {
1374 return Snapshot();
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) {
1391 return false;
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
1407 * to
1408 * @param aSource Source rectangle in aSurface coordinates, this area of
1409 * aSurface
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,
1455 const Point& aDest,
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
1520 * operation
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,
1635 Point aOffset,
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
1674 * be ignored.
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
1690 * limited in size.
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
1713 * limited in size.
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
1735 * targets.
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
1755 * time.
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
1777 * NativeSurface.
1779 virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(
1780 const NativeSurface& aSurface) const = 0;
1783 * Create a DrawTarget whose snapshot is optimized for use with this
1784 * DrawTarget.
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
1791 * DrawTarget.
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
1802 * surface.
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 {
1820 return true;
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
1829 * its size.
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
1882 * inputs.
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
1965 * data.
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
1971 * reason.
1973 virtual void DetachAllSnapshots() = 0;
1976 * Remove all clips in the DrawTarget.
1978 virtual bool RemoveAllClips() { return false; }
1980 protected:
1981 UserData mUserData;
1982 Matrix mTransform;
1983 IntRect mOpaqueRect;
1984 bool mTransformDirty : 1;
1985 bool mPermitSubpixelAA : 1;
1987 SurfaceFormat mFormat;
1990 class DrawEventRecorder : public external::AtomicRefCounted<DrawEventRecorder> {
1991 public:
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;
1999 struct Tile {
2000 RefPtr<DrawTarget> mDrawTarget;
2001 IntPoint mTileOrigin;
2004 struct TileSet {
2005 Tile* mTiles;
2006 size_t mTileCount;
2009 struct Config {
2010 LogForwarder* mLogForwarder;
2011 int32_t mMaxTextureSize;
2012 int32_t mMaxAllocSize;
2014 Config()
2015 : mLogForwarder(nullptr),
2016 mMaxTextureSize(kReasonableSurfaceSize),
2017 mMaxAllocSize(52000000) {}
2020 class GFX2D_API Factory {
2021 using char_type = filesystem::Path::value_type;
2023 public:
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);
2082 #ifdef XP_DARWIN
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);
2087 #endif
2089 #ifdef MOZ_WIDGET_GTK
2090 static already_AddRefed<ScaledFont> CreateScaledFontForFontconfigFont(
2091 const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
2092 RefPtr<SharedFTFace> aFace, FcPattern* aPattern);
2093 #endif
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);
2099 #endif
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,
2121 uint32_t aIndex);
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;
2175 private:
2176 static Config* sConfig;
2178 public:
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();
2189 private:
2190 static bool mBGRSubpixelOrder;
2192 public:
2193 static already_AddRefed<DrawTarget> CreateDrawTargetWithSkCanvas(
2194 SkCanvas* aCanvas);
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,
2206 int aFaceIndex);
2207 static already_AddRefed<SharedFTFace> NewSharedFTFace(FT_Library aFTLibrary,
2208 const char* aFilename,
2209 int aFaceIndex);
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,
2217 int32_t aFlags);
2219 private:
2220 static FT_Library mFTLibrary;
2221 static StaticMutex mFTLock;
2223 public:
2224 #endif
2226 #ifdef WIN32
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,
2257 Float aSize);
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);
2277 private:
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);
2295 protected:
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;
2304 #endif // WIN32
2307 class MOZ_RAII AutoSerializeWithMoz2D final {
2308 public:
2309 explicit AutoSerializeWithMoz2D(BackendType aBackendType);
2310 ~AutoSerializeWithMoz2D();
2312 private:
2313 #if defined(WIN32)
2314 RefPtr<ID2D1Multithread> mMT;
2315 #endif
2318 } // namespace gfx
2319 } // namespace mozilla
2321 #endif // _MOZILLA_GFX_2D_H