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