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