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