RecordedEventImpl.h (143146B)
1 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef MOZILLA_GFX_RECORDEDEVENTIMPL_H_ 7 #define MOZILLA_GFX_RECORDEDEVENTIMPL_H_ 8 9 #include "RecordedEvent.h" 10 11 #include "PathRecording.h" 12 #include "RecordingTypes.h" 13 #include "Tools.h" 14 #include "Filters.h" 15 #include "Logging.h" 16 #include "ScaledFontBase.h" 17 #include "SFNTData.h" 18 19 #include "mozilla/dom/CanvasRenderingContextHelper.h" 20 #include "mozilla/layers/BuildConstants.h" 21 #include "mozilla/layers/LayersSurfaces.h" 22 #include "mozilla/ipc/SerializeToBytesUtil.h" 23 24 namespace mozilla { 25 namespace gfx { 26 27 class RecordedDrawTargetCreation 28 : public RecordedEventDerived<RecordedDrawTargetCreation> { 29 public: 30 RecordedDrawTargetCreation(ReferencePtr aRefPtr, BackendType aType, 31 const IntRect& aRect, SurfaceFormat aFormat, 32 bool aHasExistingData = false, 33 SourceSurface* aExistingData = nullptr) 34 : RecordedEventDerived(DRAWTARGETCREATION), 35 mRefPtr(aRefPtr), 36 mBackendType(aType), 37 mRect(aRect), 38 mFormat(aFormat), 39 mHasExistingData(aHasExistingData), 40 mExistingData(aExistingData) {} 41 42 bool PlayEvent(Translator* aTranslator) const override; 43 44 template <class S> 45 void Record(S& aStream) const; 46 virtual void OutputSimpleEventInfo( 47 std::stringstream& aStringStream) const override; 48 49 std::string GetName() const override { return "DrawTarget Creation"; } 50 51 ReferencePtr mRefPtr; 52 BackendType mBackendType; 53 IntRect mRect; 54 SurfaceFormat mFormat; 55 bool mHasExistingData = false; 56 RefPtr<SourceSurface> mExistingData; 57 58 private: 59 friend class RecordedEvent; 60 61 template <class S> 62 MOZ_IMPLICIT RecordedDrawTargetCreation(S& aStream); 63 }; 64 65 class RecordedDrawTargetDestruction 66 : public RecordedEventDerived<RecordedDrawTargetDestruction> { 67 public: 68 MOZ_IMPLICIT RecordedDrawTargetDestruction(ReferencePtr aRefPtr) 69 : RecordedEventDerived(DRAWTARGETDESTRUCTION), 70 mRefPtr(aRefPtr), 71 mBackendType(BackendType::NONE) {} 72 73 bool PlayEvent(Translator* aTranslator) const override; 74 75 template <class S> 76 void Record(S& aStream) const; 77 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 78 79 std::string GetName() const override { return "DrawTarget Destruction"; } 80 81 ReferencePtr mRefPtr; 82 83 BackendType mBackendType; 84 85 private: 86 friend class RecordedEvent; 87 88 template <class S> 89 MOZ_IMPLICIT RecordedDrawTargetDestruction(S& aStream); 90 }; 91 92 class RecordedSetCurrentDrawTarget 93 : public RecordedEventDerived<RecordedSetCurrentDrawTarget> { 94 public: 95 MOZ_IMPLICIT RecordedSetCurrentDrawTarget(ReferencePtr aRefPtr) 96 : RecordedEventDerived(SETCURRENTDRAWTARGET), mRefPtr(aRefPtr) {} 97 98 bool PlayEvent(Translator* aTranslator) const override; 99 100 template <class S> 101 void Record(S& aStream) const; 102 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 103 104 std::string GetName() const override { return "SetCurrentDrawTarget"; } 105 106 ReferencePtr mRefPtr; 107 108 private: 109 friend class RecordedEvent; 110 111 template <class S> 112 MOZ_IMPLICIT RecordedSetCurrentDrawTarget(S& aStream); 113 }; 114 115 class RecordedCreateSimilarDrawTarget 116 : public RecordedEventDerived<RecordedCreateSimilarDrawTarget> { 117 public: 118 RecordedCreateSimilarDrawTarget(ReferencePtr aRefPtr, const IntSize& aSize, 119 SurfaceFormat aFormat) 120 : RecordedEventDerived(CREATESIMILARDRAWTARGET), 121 mRefPtr(aRefPtr), 122 mSize(aSize), 123 mFormat(aFormat) {} 124 125 bool PlayEvent(Translator* aTranslator) const override; 126 127 template <class S> 128 void Record(S& aStream) const; 129 virtual void OutputSimpleEventInfo( 130 std::stringstream& aStringStream) const override; 131 132 std::string GetName() const override { return "CreateSimilarDrawTarget"; } 133 134 ReferencePtr mRefPtr; 135 IntSize mSize; 136 SurfaceFormat mFormat; 137 138 private: 139 friend class RecordedEvent; 140 141 template <class S> 142 MOZ_IMPLICIT RecordedCreateSimilarDrawTarget(S& aStream); 143 }; 144 145 class RecordedCreateClippedDrawTarget 146 : public RecordedEventDerived<RecordedCreateClippedDrawTarget> { 147 public: 148 RecordedCreateClippedDrawTarget(ReferencePtr aRefPtr, const Rect& aBounds, 149 SurfaceFormat aFormat) 150 : RecordedEventDerived(CREATECLIPPEDDRAWTARGET), 151 mRefPtr(aRefPtr), 152 mBounds(aBounds), 153 mFormat(aFormat) {} 154 155 bool PlayEvent(Translator* aTranslator) const override; 156 157 template <class S> 158 void Record(S& aStream) const; 159 virtual void OutputSimpleEventInfo( 160 std::stringstream& aStringStream) const override; 161 162 std::string GetName() const override { return "CreateClippedDrawTarget"; } 163 164 ReferencePtr mRefPtr; 165 Rect mBounds; 166 SurfaceFormat mFormat; 167 168 private: 169 friend class RecordedEvent; 170 171 template <class S> 172 MOZ_IMPLICIT RecordedCreateClippedDrawTarget(S& aStream); 173 }; 174 175 class RecordedCreateDrawTargetForFilter 176 : public RecordedEventDerived<RecordedCreateDrawTargetForFilter> { 177 public: 178 RecordedCreateDrawTargetForFilter(ReferencePtr aRefPtr, 179 const IntSize& aMaxSize, 180 SurfaceFormat aFormat, FilterNode* aFilter, 181 FilterNode* aSource, 182 const Rect& aSourceRect, 183 const Point& aDestPoint) 184 : RecordedEventDerived(CREATEDRAWTARGETFORFILTER), 185 mRefPtr(aRefPtr), 186 mMaxSize(aMaxSize), 187 mFormat(aFormat), 188 mFilter(aFilter), 189 mSource(aSource), 190 mSourceRect(aSourceRect), 191 mDestPoint(aDestPoint) {} 192 193 bool PlayEvent(Translator* aTranslator) const override; 194 195 template <class S> 196 void Record(S& aStream) const; 197 virtual void OutputSimpleEventInfo( 198 std::stringstream& aStringStream) const override; 199 200 std::string GetName() const override { 201 return "CreateSimilarDrawTargetForFilter"; 202 } 203 204 ReferencePtr mRefPtr; 205 IntSize mMaxSize; 206 SurfaceFormat mFormat; 207 ReferencePtr mFilter; 208 ReferencePtr mSource; 209 Rect mSourceRect; 210 Point mDestPoint; 211 212 private: 213 friend class RecordedEvent; 214 215 template <class S> 216 MOZ_IMPLICIT RecordedCreateDrawTargetForFilter(S& aStream); 217 }; 218 219 class RecordedFillRect : public RecordedEventDerived<RecordedFillRect> { 220 public: 221 RecordedFillRect(const Rect& aRect, const Pattern& aPattern, 222 const DrawOptions& aOptions) 223 : RecordedEventDerived(FILLRECT), 224 mRect(aRect), 225 mPattern(), 226 mOptions(aOptions) { 227 StorePattern(mPattern, aPattern); 228 } 229 230 bool PlayEvent(Translator* aTranslator) const override; 231 232 template <class S> 233 void Record(S& aStream) const; 234 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 235 236 std::string GetName() const override { return "FillRect"; } 237 238 private: 239 friend class RecordedEvent; 240 241 template <class S> 242 MOZ_IMPLICIT RecordedFillRect(S& aStream); 243 244 Rect mRect; 245 PatternStorage mPattern; 246 DrawOptions mOptions; 247 }; 248 249 class RecordedStrokeRect : public RecordedEventDerived<RecordedStrokeRect>, 250 public RecordedStrokeOptionsMixin { 251 public: 252 RecordedStrokeRect(const Rect& aRect, const Pattern& aPattern, 253 const StrokeOptions& aStrokeOptions, 254 const DrawOptions& aOptions) 255 : RecordedEventDerived(STROKERECT), 256 mRect(aRect), 257 mPattern(), 258 mStrokeOptions(aStrokeOptions), 259 mOptions(aOptions) { 260 StorePattern(mPattern, aPattern); 261 } 262 263 bool PlayEvent(Translator* aTranslator) const override; 264 265 template <class S> 266 void Record(S& aStream) const; 267 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 268 269 std::string GetName() const override { return "StrokeRect"; } 270 271 private: 272 friend class RecordedEvent; 273 274 template <class S> 275 MOZ_IMPLICIT RecordedStrokeRect(S& aStream); 276 277 Rect mRect; 278 PatternStorage mPattern; 279 StrokeOptions mStrokeOptions; 280 DrawOptions mOptions; 281 }; 282 283 class RecordedStrokeLine : public RecordedEventDerived<RecordedStrokeLine>, 284 public RecordedStrokeOptionsMixin { 285 public: 286 RecordedStrokeLine(const Point& aBegin, const Point& aEnd, 287 const Pattern& aPattern, 288 const StrokeOptions& aStrokeOptions, 289 const DrawOptions& aOptions) 290 : RecordedEventDerived(STROKELINE), 291 mBegin(aBegin), 292 mEnd(aEnd), 293 mPattern(), 294 mStrokeOptions(aStrokeOptions), 295 mOptions(aOptions) { 296 StorePattern(mPattern, aPattern); 297 } 298 299 bool PlayEvent(Translator* aTranslator) const override; 300 301 template <class S> 302 void Record(S& aStream) const; 303 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 304 305 std::string GetName() const override { return "StrokeLine"; } 306 307 private: 308 friend class RecordedEvent; 309 310 template <class S> 311 MOZ_IMPLICIT RecordedStrokeLine(S& aStream); 312 313 Point mBegin; 314 Point mEnd; 315 PatternStorage mPattern; 316 StrokeOptions mStrokeOptions; 317 DrawOptions mOptions; 318 }; 319 320 class RecordedStrokeCircle : public RecordedEventDerived<RecordedStrokeCircle>, 321 public RecordedStrokeOptionsMixin { 322 public: 323 RecordedStrokeCircle(Circle aCircle, const Pattern& aPattern, 324 const StrokeOptions& aStrokeOptions, 325 const DrawOptions& aOptions) 326 : RecordedEventDerived(STROKECIRCLE), 327 mCircle(aCircle), 328 mPattern(), 329 mStrokeOptions(aStrokeOptions), 330 mOptions(aOptions) { 331 StorePattern(mPattern, aPattern); 332 } 333 334 bool PlayEvent(Translator* aTranslator) const override; 335 336 template <class S> 337 void Record(S& aStream) const; 338 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 339 340 std::string GetName() const override { return "StrokeCircle"; } 341 342 private: 343 friend class RecordedEvent; 344 345 template <class S> 346 MOZ_IMPLICIT RecordedStrokeCircle(S& aStream); 347 348 Circle mCircle; 349 PatternStorage mPattern; 350 StrokeOptions mStrokeOptions; 351 DrawOptions mOptions; 352 }; 353 354 class RecordedFill : public RecordedEventDerived<RecordedFill> { 355 public: 356 RecordedFill(ReferencePtr aPath, const Pattern& aPattern, 357 const DrawOptions& aOptions) 358 : RecordedEventDerived(FILL), 359 mPath(aPath), 360 mPattern(), 361 mOptions(aOptions) { 362 StorePattern(mPattern, aPattern); 363 } 364 365 bool PlayEvent(Translator* aTranslator) const override; 366 367 template <class S> 368 void Record(S& aStream) const; 369 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 370 371 std::string GetName() const override { return "Fill"; } 372 373 private: 374 friend class RecordedEvent; 375 376 template <class S> 377 MOZ_IMPLICIT RecordedFill(S& aStream); 378 379 ReferencePtr mPath; 380 PatternStorage mPattern; 381 DrawOptions mOptions; 382 }; 383 384 class RecordedFillCircle : public RecordedEventDerived<RecordedFillCircle> { 385 public: 386 RecordedFillCircle(Circle aCircle, const Pattern& aPattern, 387 const DrawOptions& aOptions) 388 : RecordedEventDerived(FILLCIRCLE), 389 mCircle(aCircle), 390 mPattern(), 391 mOptions(aOptions) { 392 StorePattern(mPattern, aPattern); 393 } 394 395 bool PlayEvent(Translator* aTranslator) const override; 396 397 template <class S> 398 void Record(S& aStream) const; 399 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 400 401 std::string GetName() const override { return "FillCircle"; } 402 403 private: 404 friend class RecordedEvent; 405 406 template <class S> 407 MOZ_IMPLICIT RecordedFillCircle(S& aStream); 408 409 Circle mCircle; 410 PatternStorage mPattern; 411 DrawOptions mOptions; 412 }; 413 414 template <class Derived> 415 class RecordedDrawGlyphs : public RecordedEventDerived<Derived> { 416 public: 417 RecordedDrawGlyphs(RecordedEvent::EventType aType, ReferencePtr aScaledFont, 418 const Pattern& aPattern, const DrawOptions& aOptions, 419 const Glyph* aGlyphs, uint32_t aNumGlyphs) 420 : RecordedEventDerived<Derived>(aType), 421 mScaledFont(aScaledFont), 422 mPattern(), 423 mOptions(aOptions) { 424 this->StorePattern(mPattern, aPattern); 425 mGlyphs.Assign(aGlyphs, aNumGlyphs); 426 } 427 428 bool PlayEvent(Translator* aTranslator) const override; 429 430 template <class S> 431 void Record(S& aStream) const; 432 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 433 434 protected: 435 friend class RecordedEvent; 436 437 template <class S> 438 RecordedDrawGlyphs(RecordedEvent::EventType aType, S& aStream); 439 440 virtual void DrawGlyphs(DrawTarget* aDT, ScaledFont* aScaledFont, 441 const GlyphBuffer& aBuffer, 442 const Pattern& aPattern) const = 0; 443 444 ReferencePtr mScaledFont; 445 PatternStorage mPattern; 446 DrawOptions mOptions; 447 RecordedEventArray<Glyph, uint32_t> mGlyphs; 448 }; 449 450 class RecordedFillGlyphs : public RecordedDrawGlyphs<RecordedFillGlyphs> { 451 public: 452 RecordedFillGlyphs(ReferencePtr aScaledFont, const Pattern& aPattern, 453 const DrawOptions& aOptions, const Glyph* aGlyphs, 454 uint32_t aNumGlyphs) 455 : RecordedDrawGlyphs(FILLGLYPHS, aScaledFont, aPattern, aOptions, aGlyphs, 456 aNumGlyphs) {} 457 458 std::string GetName() const override { return "FillGlyphs"; } 459 460 private: 461 friend class RecordedEvent; 462 463 template <class S> 464 MOZ_IMPLICIT RecordedFillGlyphs(S& aStream) 465 : RecordedDrawGlyphs(FILLGLYPHS, aStream) {} 466 467 void DrawGlyphs(DrawTarget* aDT, ScaledFont* aScaledFont, 468 const GlyphBuffer& aBuffer, 469 const Pattern& aPattern) const override { 470 aDT->FillGlyphs(aScaledFont, aBuffer, aPattern, mOptions); 471 } 472 }; 473 474 class RecordedStrokeGlyphs : public RecordedDrawGlyphs<RecordedStrokeGlyphs>, 475 public RecordedStrokeOptionsMixin { 476 public: 477 RecordedStrokeGlyphs(ReferencePtr aScaledFont, const Pattern& aPattern, 478 const StrokeOptions& aStrokeOptions, 479 const DrawOptions& aOptions, const Glyph* aGlyphs, 480 uint32_t aNumGlyphs) 481 : RecordedDrawGlyphs(STROKEGLYPHS, aScaledFont, aPattern, aOptions, 482 aGlyphs, aNumGlyphs), 483 mStrokeOptions(aStrokeOptions) {} 484 485 std::string GetName() const override { return "StrokeGlyphs"; } 486 487 template <class S> 488 void Record(S& aStream) const { 489 RecordedDrawGlyphs::Record(aStream); 490 RecordStrokeOptions(aStream, mStrokeOptions); 491 } 492 493 private: 494 friend class RecordedEvent; 495 496 template <class S> 497 MOZ_IMPLICIT RecordedStrokeGlyphs(S& aStream) 498 : RecordedDrawGlyphs(STROKEGLYPHS, aStream) { 499 ReadStrokeOptions(aStream, mStrokeOptions); 500 } 501 502 void DrawGlyphs(DrawTarget* aDT, ScaledFont* aScaledFont, 503 const GlyphBuffer& aBuffer, 504 const Pattern& aPattern) const override { 505 aDT->StrokeGlyphs(aScaledFont, aBuffer, aPattern, mStrokeOptions, mOptions); 506 } 507 508 StrokeOptions mStrokeOptions; 509 }; 510 511 class RecordedMask : public RecordedEventDerived<RecordedMask> { 512 public: 513 RecordedMask(const Pattern& aSource, const Pattern& aMask, 514 const DrawOptions& aOptions) 515 : RecordedEventDerived(MASK), mSource(), mMask(), mOptions(aOptions) { 516 StorePattern(mSource, aSource); 517 StorePattern(mMask, aMask); 518 } 519 520 bool PlayEvent(Translator* aTranslator) const override; 521 522 template <class S> 523 void Record(S& aStream) const; 524 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 525 526 std::string GetName() const override { return "Mask"; } 527 528 private: 529 friend class RecordedEvent; 530 531 template <class S> 532 MOZ_IMPLICIT RecordedMask(S& aStream); 533 534 PatternStorage mSource; 535 PatternStorage mMask; 536 DrawOptions mOptions; 537 }; 538 539 class RecordedStroke : public RecordedEventDerived<RecordedStroke>, 540 public RecordedStrokeOptionsMixin { 541 public: 542 RecordedStroke(ReferencePtr aPath, const Pattern& aPattern, 543 const StrokeOptions& aStrokeOptions, 544 const DrawOptions& aOptions) 545 : RecordedEventDerived(STROKE), 546 mPath(aPath), 547 mPattern(), 548 mStrokeOptions(aStrokeOptions), 549 mOptions(aOptions) { 550 StorePattern(mPattern, aPattern); 551 } 552 553 bool PlayEvent(Translator* aTranslator) const override; 554 555 template <class S> 556 void Record(S& aStream) const; 557 virtual void OutputSimpleEventInfo( 558 std::stringstream& aStringStream) const override; 559 560 std::string GetName() const override { return "Stroke"; } 561 562 private: 563 friend class RecordedEvent; 564 565 template <class S> 566 MOZ_IMPLICIT RecordedStroke(S& aStream); 567 568 ReferencePtr mPath; 569 PatternStorage mPattern; 570 StrokeOptions mStrokeOptions; 571 DrawOptions mOptions; 572 }; 573 574 class RecordedClearRect : public RecordedEventDerived<RecordedClearRect> { 575 public: 576 explicit RecordedClearRect(const Rect& aRect) 577 : RecordedEventDerived(CLEARRECT), mRect(aRect) {} 578 579 bool PlayEvent(Translator* aTranslator) const override; 580 581 template <class S> 582 void Record(S& aStream) const; 583 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 584 585 std::string GetName() const override { return "ClearRect"; } 586 587 private: 588 friend class RecordedEvent; 589 590 template <class S> 591 MOZ_IMPLICIT RecordedClearRect(S& aStream); 592 593 Rect mRect; 594 }; 595 596 class RecordedCopySurface : public RecordedEventDerived<RecordedCopySurface> { 597 public: 598 RecordedCopySurface(ReferencePtr aSourceSurface, const IntRect& aSourceRect, 599 const IntPoint& aDest) 600 : RecordedEventDerived(COPYSURFACE), 601 mSourceSurface(aSourceSurface), 602 mSourceRect(aSourceRect), 603 mDest(aDest) {} 604 605 bool PlayEvent(Translator* aTranslator) const override; 606 607 template <class S> 608 void Record(S& aStream) const; 609 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 610 611 std::string GetName() const override { return "CopySurface"; } 612 613 private: 614 friend class RecordedEvent; 615 616 template <class S> 617 MOZ_IMPLICIT RecordedCopySurface(S& aStream); 618 619 ReferencePtr mSourceSurface; 620 IntRect mSourceRect; 621 IntPoint mDest; 622 }; 623 624 class RecordedPushClip : public RecordedEventDerived<RecordedPushClip> { 625 public: 626 explicit RecordedPushClip(ReferencePtr aPath) 627 : RecordedEventDerived(PUSHCLIP), mPath(aPath) {} 628 629 bool PlayEvent(Translator* aTranslator) const override; 630 631 template <class S> 632 void Record(S& aStream) const; 633 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 634 635 std::string GetName() const override { return "PushClip"; } 636 637 private: 638 friend class RecordedEvent; 639 640 template <class S> 641 MOZ_IMPLICIT RecordedPushClip(S& aStream); 642 643 ReferencePtr mPath; 644 }; 645 646 class RecordedPushClipRect : public RecordedEventDerived<RecordedPushClipRect> { 647 public: 648 explicit RecordedPushClipRect(const Rect& aRect) 649 : RecordedEventDerived(PUSHCLIPRECT), mRect(aRect) {} 650 651 bool PlayEvent(Translator* aTranslator) const override; 652 653 template <class S> 654 void Record(S& aStream) const; 655 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 656 657 std::string GetName() const override { return "PushClipRect"; } 658 659 private: 660 friend class RecordedEvent; 661 662 template <class S> 663 MOZ_IMPLICIT RecordedPushClipRect(S& aStream); 664 665 Rect mRect; 666 }; 667 668 class RecordedPopClip : public RecordedEventDerived<RecordedPopClip> { 669 public: 670 MOZ_IMPLICIT RecordedPopClip() : RecordedEventDerived(POPCLIP) {} 671 672 bool PlayEvent(Translator* aTranslator) const override; 673 674 template <class S> 675 void Record(S& aStream) const; 676 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 677 678 std::string GetName() const override { return "PopClip"; } 679 680 private: 681 friend class RecordedEvent; 682 683 template <class S> 684 MOZ_IMPLICIT RecordedPopClip(S& aStream); 685 }; 686 687 class RecordedRemoveAllClips 688 : public RecordedEventDerived<RecordedRemoveAllClips> { 689 public: 690 MOZ_IMPLICIT RecordedRemoveAllClips() 691 : RecordedEventDerived(REMOVEALLCLIPS) {} 692 693 bool PlayEvent(Translator* aTranslator) const override; 694 695 template <class S> 696 void Record(S& aStream) const; 697 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 698 699 std::string GetName() const override { return "RemoveAllClips"; } 700 701 private: 702 friend class RecordedEvent; 703 704 template <class S> 705 MOZ_IMPLICIT RecordedRemoveAllClips(S& aStream); 706 }; 707 708 class RecordedPushLayer : public RecordedEventDerived<RecordedPushLayer> { 709 public: 710 RecordedPushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask, 711 const Matrix& aMaskTransform, const IntRect& aBounds, 712 bool aCopyBackground) 713 : RecordedEventDerived(PUSHLAYER), 714 mOpaque(aOpaque), 715 mOpacity(aOpacity), 716 mMask(aMask), 717 mMaskTransform(aMaskTransform), 718 mBounds(aBounds), 719 mCopyBackground(aCopyBackground) {} 720 721 bool PlayEvent(Translator* aTranslator) const override; 722 723 template <class S> 724 void Record(S& aStream) const; 725 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 726 727 std::string GetName() const override { return "PushLayer"; } 728 729 private: 730 friend class RecordedEvent; 731 732 template <class S> 733 MOZ_IMPLICIT RecordedPushLayer(S& aStream); 734 735 bool mOpaque = false; 736 Float mOpacity = 1.0f; 737 ReferencePtr mMask; 738 Matrix mMaskTransform; 739 IntRect mBounds; 740 bool mCopyBackground = false; 741 }; 742 743 class RecordedPushLayerWithBlend 744 : public RecordedEventDerived<RecordedPushLayerWithBlend> { 745 public: 746 RecordedPushLayerWithBlend(bool aOpaque, Float aOpacity, SourceSurface* aMask, 747 const Matrix& aMaskTransform, 748 const IntRect& aBounds, bool aCopyBackground, 749 CompositionOp aCompositionOp) 750 : RecordedEventDerived(PUSHLAYERWITHBLEND), 751 mOpaque(aOpaque), 752 mOpacity(aOpacity), 753 mMask(aMask), 754 mMaskTransform(aMaskTransform), 755 mBounds(aBounds), 756 mCopyBackground(aCopyBackground), 757 mCompositionOp(aCompositionOp) {} 758 759 bool PlayEvent(Translator* aTranslator) const override; 760 761 template <class S> 762 void Record(S& aStream) const; 763 virtual void OutputSimpleEventInfo( 764 std::stringstream& aStringStream) const override; 765 766 std::string GetName() const override { return "PushLayerWithBlend"; } 767 768 private: 769 friend class RecordedEvent; 770 771 template <class S> 772 MOZ_IMPLICIT RecordedPushLayerWithBlend(S& aStream); 773 774 bool mOpaque = false; 775 Float mOpacity = 1.0f; 776 ReferencePtr mMask; 777 Matrix mMaskTransform; 778 IntRect mBounds; 779 bool mCopyBackground = false; 780 CompositionOp mCompositionOp = CompositionOp::OP_OVER; 781 }; 782 783 class RecordedPopLayer : public RecordedEventDerived<RecordedPopLayer> { 784 public: 785 RecordedPopLayer() : RecordedEventDerived(POPLAYER) {} 786 787 bool PlayEvent(Translator* aTranslator) const override; 788 789 template <class S> 790 void Record(S& aStream) const; 791 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 792 793 std::string GetName() const override { return "PopLayer"; } 794 795 private: 796 friend class RecordedEvent; 797 798 template <class S> 799 MOZ_IMPLICIT RecordedPopLayer(S& aStream); 800 }; 801 802 class RecordedSetPermitSubpixelAA 803 : public RecordedEventDerived<RecordedSetPermitSubpixelAA> { 804 public: 805 explicit RecordedSetPermitSubpixelAA(bool aPermitSubpixelAA) 806 : RecordedEventDerived(SETPERMITSUBPIXELAA), 807 mPermitSubpixelAA(aPermitSubpixelAA) {} 808 809 bool PlayEvent(Translator* aTranslator) const override; 810 811 template <class S> 812 void Record(S& aStream) const; 813 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 814 815 std::string GetName() const override { return "SetPermitSubpixelAA"; } 816 817 private: 818 friend class RecordedEvent; 819 820 template <class S> 821 MOZ_IMPLICIT RecordedSetPermitSubpixelAA(S& aStream); 822 823 bool mPermitSubpixelAA = false; 824 }; 825 826 class RecordedSetTransform : public RecordedEventDerived<RecordedSetTransform> { 827 public: 828 explicit RecordedSetTransform(const Matrix& aTransform) 829 : RecordedEventDerived(SETTRANSFORM), mTransform(aTransform) {} 830 831 bool PlayEvent(Translator* aTranslator) const override; 832 833 template <class S> 834 void Record(S& aStream) const; 835 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 836 837 std::string GetName() const override { return "SetTransform"; } 838 839 Matrix mTransform; 840 841 private: 842 friend class RecordedEvent; 843 844 template <class S> 845 MOZ_IMPLICIT RecordedSetTransform(S& aStream); 846 }; 847 848 class RecordedDrawSurface : public RecordedEventDerived<RecordedDrawSurface> { 849 public: 850 RecordedDrawSurface(ReferencePtr aRefSource, const Rect& aDest, 851 const Rect& aSource, const DrawSurfaceOptions& aDSOptions, 852 const DrawOptions& aOptions) 853 : RecordedEventDerived(DRAWSURFACE), 854 mRefSource(aRefSource), 855 mDest(aDest), 856 mSource(aSource), 857 mDSOptions(aDSOptions), 858 mOptions(aOptions) {} 859 860 bool PlayEvent(Translator* aTranslator) const override; 861 862 template <class S> 863 void Record(S& aStream) const; 864 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 865 866 std::string GetName() const override { return "DrawSurface"; } 867 868 private: 869 friend class RecordedEvent; 870 871 template <class S> 872 MOZ_IMPLICIT RecordedDrawSurface(S& aStream); 873 874 ReferencePtr mRefSource; 875 Rect mDest; 876 Rect mSource; 877 DrawSurfaceOptions mDSOptions; 878 DrawOptions mOptions; 879 }; 880 881 class RecordedDrawSurfaceDescriptor 882 : public RecordedEventDerived<RecordedDrawSurfaceDescriptor> { 883 public: 884 RecordedDrawSurfaceDescriptor(const layers::SurfaceDescriptor& aDesc, 885 const Rect& aDest, const Rect& aSource, 886 const DrawSurfaceOptions& aDSOptions, 887 const DrawOptions& aOptions) 888 : RecordedEventDerived(DRAWSURFACEDESCRIPTOR), 889 mDesc(aDesc), 890 mDest(aDest), 891 mSource(aSource), 892 mDSOptions(aDSOptions), 893 mOptions(aOptions) {} 894 895 bool PlayEvent(Translator* aTranslator) const override; 896 897 template <class S> 898 void Record(S& aStream) const; 899 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 900 901 std::string GetName() const override { return "DrawSurfaceDescriptor"; } 902 903 private: 904 friend class RecordedEvent; 905 906 template <class S> 907 MOZ_IMPLICIT RecordedDrawSurfaceDescriptor(S& aStream); 908 909 layers::SurfaceDescriptor mDesc; 910 Rect mDest; 911 Rect mSource; 912 DrawSurfaceOptions mDSOptions; 913 DrawOptions mOptions; 914 }; 915 916 class RecordedDrawDependentSurface 917 : public RecordedEventDerived<RecordedDrawDependentSurface> { 918 public: 919 RecordedDrawDependentSurface(uint64_t aId, const Rect& aDest) 920 : RecordedEventDerived(DRAWDEPENDENTSURFACE), mId(aId), mDest(aDest) {} 921 922 bool PlayEvent(Translator* aTranslator) const override; 923 924 template <class S> 925 void Record(S& aStream) const; 926 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 927 928 std::string GetName() const override { return "DrawDependentSurface"; } 929 930 private: 931 friend class RecordedEvent; 932 933 template <class S> 934 MOZ_IMPLICIT RecordedDrawDependentSurface(S& aStream); 935 936 uint64_t mId; 937 Rect mDest; 938 }; 939 940 class RecordedDrawSurfaceWithShadow 941 : public RecordedEventDerived<RecordedDrawSurfaceWithShadow> { 942 public: 943 RecordedDrawSurfaceWithShadow(ReferencePtr aRefSource, const Point& aDest, 944 const ShadowOptions& aShadow, CompositionOp aOp) 945 : RecordedEventDerived(DRAWSURFACEWITHSHADOW), 946 mRefSource(aRefSource), 947 mDest(aDest), 948 mShadow(aShadow), 949 mOp(aOp) {} 950 951 bool PlayEvent(Translator* aTranslator) const override; 952 953 template <class S> 954 void Record(S& aStream) const; 955 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 956 957 std::string GetName() const override { return "DrawSurfaceWithShadow"; } 958 959 private: 960 friend class RecordedEvent; 961 962 template <class S> 963 MOZ_IMPLICIT RecordedDrawSurfaceWithShadow(S& aStream); 964 965 ReferencePtr mRefSource; 966 Point mDest; 967 ShadowOptions mShadow; 968 CompositionOp mOp; 969 }; 970 971 class RecordedDrawShadow : public RecordedEventDerived<RecordedDrawShadow>, 972 public RecordedStrokeOptionsMixin { 973 public: 974 RecordedDrawShadow(ReferencePtr aPath, const Pattern& aPattern, 975 const ShadowOptions& aShadow, const DrawOptions& aOptions, 976 const StrokeOptions* aStrokeOptions) 977 : RecordedEventDerived(DRAWSHADOW), 978 mPath(aPath), 979 mPattern(), 980 mShadow(aShadow), 981 mOptions(aOptions), 982 mHasStrokeOptions(!!aStrokeOptions), 983 mStrokeOptions(aStrokeOptions ? *aStrokeOptions : StrokeOptions()) { 984 StorePattern(mPattern, aPattern); 985 } 986 987 bool PlayEvent(Translator* aTranslator) const override; 988 989 template <class S> 990 void Record(S& aStream) const; 991 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 992 993 std::string GetName() const override { return "DrawShadow"; } 994 995 private: 996 friend class RecordedEvent; 997 998 template <class S> 999 MOZ_IMPLICIT RecordedDrawShadow(S& aStream); 1000 1001 ReferencePtr mPath; 1002 PatternStorage mPattern; 1003 ShadowOptions mShadow; 1004 DrawOptions mOptions; 1005 bool mHasStrokeOptions = false; 1006 StrokeOptions mStrokeOptions; 1007 }; 1008 1009 class RecordedDrawFilter : public RecordedEventDerived<RecordedDrawFilter> { 1010 public: 1011 RecordedDrawFilter(ReferencePtr aNode, const Rect& aSourceRect, 1012 const Point& aDestPoint, const DrawOptions& aOptions) 1013 : RecordedEventDerived(DRAWFILTER), 1014 mNode(aNode), 1015 mSourceRect(aSourceRect), 1016 mDestPoint(aDestPoint), 1017 mOptions(aOptions) {} 1018 1019 bool PlayEvent(Translator* aTranslator) const override; 1020 1021 template <class S> 1022 void Record(S& aStream) const; 1023 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1024 1025 std::string GetName() const override { return "DrawFilter"; } 1026 1027 private: 1028 friend class RecordedEvent; 1029 1030 template <class S> 1031 MOZ_IMPLICIT RecordedDrawFilter(S& aStream); 1032 1033 ReferencePtr mNode; 1034 Rect mSourceRect; 1035 Point mDestPoint; 1036 DrawOptions mOptions; 1037 }; 1038 1039 class RecordedPathCreation : public RecordedEventDerived<RecordedPathCreation> { 1040 public: 1041 MOZ_IMPLICIT RecordedPathCreation(PathRecording* aPath); 1042 1043 bool PlayEvent(Translator* aTranslator) const override; 1044 1045 template <class S> 1046 void Record(S& aStream) const; 1047 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1048 1049 std::string GetName() const override { return "Path Creation"; } 1050 1051 private: 1052 friend class RecordedEvent; 1053 1054 ReferencePtr mDT; 1055 ReferencePtr mRefPtr; 1056 FillRule mFillRule; 1057 RefPtr<PathRecording> mPath; 1058 UniquePtr<PathOps> mPathOps; 1059 1060 template <class S> 1061 MOZ_IMPLICIT RecordedPathCreation(S& aStream); 1062 }; 1063 1064 class RecordedPathDestruction 1065 : public RecordedEventDerived<RecordedPathDestruction> { 1066 public: 1067 MOZ_IMPLICIT RecordedPathDestruction(PathRecording* aPath) 1068 : RecordedEventDerived(PATHDESTRUCTION), mRefPtr(aPath) {} 1069 1070 bool PlayEvent(Translator* aTranslator) const override; 1071 1072 template <class S> 1073 void Record(S& aStream) const; 1074 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1075 1076 std::string GetName() const override { return "Path Destruction"; } 1077 1078 private: 1079 friend class RecordedEvent; 1080 1081 ReferencePtr mRefPtr; 1082 1083 template <class S> 1084 MOZ_IMPLICIT RecordedPathDestruction(S& aStream); 1085 }; 1086 1087 class RecordedSourceSurfaceCreation 1088 : public RecordedEventDerived<RecordedSourceSurfaceCreation> { 1089 public: 1090 RecordedSourceSurfaceCreation(ReferencePtr aRefPtr, 1091 const RefPtr<DataSourceSurface>& aDataSurface) 1092 : RecordedEventDerived(SOURCESURFACECREATION), 1093 mRefPtr(aRefPtr), 1094 mDataSurface(aDataSurface) {} 1095 1096 bool PlayEvent(Translator* aTranslator) const override; 1097 1098 template <class S> 1099 void Record(S& aStream) const; 1100 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1101 1102 std::string GetName() const override { return "SourceSurface Creation"; } 1103 1104 private: 1105 friend class RecordedEvent; 1106 1107 ReferencePtr mRefPtr; 1108 RefPtr<DataSourceSurface> mDataSurface; 1109 1110 template <class S> 1111 MOZ_IMPLICIT RecordedSourceSurfaceCreation(S& aStream); 1112 }; 1113 1114 class RecordedSourceSurfaceDestruction 1115 : public RecordedEventDerived<RecordedSourceSurfaceDestruction> { 1116 public: 1117 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(ReferencePtr aRefPtr) 1118 : RecordedEventDerived(SOURCESURFACEDESTRUCTION), mRefPtr(aRefPtr) {} 1119 1120 bool PlayEvent(Translator* aTranslator) const override; 1121 1122 template <class S> 1123 void Record(S& aStream) const; 1124 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1125 1126 std::string GetName() const override { return "SourceSurface Destruction"; } 1127 1128 private: 1129 friend class RecordedEvent; 1130 1131 ReferencePtr mRefPtr; 1132 1133 template <class S> 1134 MOZ_IMPLICIT RecordedSourceSurfaceDestruction(S& aStream); 1135 }; 1136 1137 class RecordedOptimizeSourceSurface 1138 : public RecordedEventDerived<RecordedOptimizeSourceSurface> { 1139 public: 1140 RecordedOptimizeSourceSurface(ReferencePtr aSurface, 1141 ReferencePtr aOptimizedSurface) 1142 : RecordedEventDerived(OPTIMIZESOURCESURFACE), 1143 mSurface(aSurface), 1144 mOptimizedSurface(aOptimizedSurface) {} 1145 1146 bool PlayEvent(Translator* aTranslator) const override; 1147 1148 template <class S> 1149 void Record(S& aStream) const; 1150 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1151 1152 std::string GetName() const override { return "OptimizeSourceSurface"; } 1153 1154 private: 1155 friend class RecordedEvent; 1156 1157 ReferencePtr mSurface; 1158 ReferencePtr mOptimizedSurface; 1159 1160 template <class S> 1161 MOZ_IMPLICIT RecordedOptimizeSourceSurface(S& aStream); 1162 }; 1163 1164 class RecordedExternalSurfaceCreation 1165 : public RecordedEventDerived<RecordedExternalSurfaceCreation> { 1166 public: 1167 RecordedExternalSurfaceCreation(ReferencePtr aRefPtr, const uint64_t aKey) 1168 : RecordedEventDerived(EXTERNALSURFACECREATION), 1169 mRefPtr(aRefPtr), 1170 mKey(aKey) {} 1171 1172 ~RecordedExternalSurfaceCreation() = default; 1173 1174 virtual bool PlayEvent(Translator* aTranslator) const; 1175 1176 template <class S> 1177 void Record(S& aStream) const; 1178 virtual void OutputSimpleEventInfo(std::stringstream& aStringStream) const; 1179 1180 virtual std::string GetName() const { 1181 return "SourceSurfaceSharedData Creation"; 1182 } 1183 1184 private: 1185 friend class RecordedEvent; 1186 1187 ReferencePtr mRefPtr; 1188 uint64_t mKey; 1189 1190 template <class S> 1191 MOZ_IMPLICIT RecordedExternalSurfaceCreation(S& aStream); 1192 }; 1193 1194 class RecordedFilterNodeCreation 1195 : public RecordedEventDerived<RecordedFilterNodeCreation> { 1196 public: 1197 RecordedFilterNodeCreation(ReferencePtr aRefPtr, FilterType aType) 1198 : RecordedEventDerived(FILTERNODECREATION), 1199 mRefPtr(aRefPtr), 1200 mType(aType) {} 1201 1202 ~RecordedFilterNodeCreation(); 1203 1204 bool PlayEvent(Translator* aTranslator) const override; 1205 1206 template <class S> 1207 void Record(S& aStream) const; 1208 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1209 1210 std::string GetName() const override { return "FilterNode Creation"; } 1211 1212 private: 1213 friend class RecordedEvent; 1214 1215 ReferencePtr mRefPtr; 1216 FilterType mType; 1217 1218 template <class S> 1219 MOZ_IMPLICIT RecordedFilterNodeCreation(S& aStream); 1220 }; 1221 1222 class RecordedDeferFilterInput 1223 : public RecordedEventDerived<RecordedDeferFilterInput>, 1224 public RecordedStrokeOptionsMixin { 1225 public: 1226 RecordedDeferFilterInput(ReferencePtr aRefPtr, ReferencePtr aPath, 1227 const Pattern& aPattern, const IntRect& aSourceRect, 1228 const IntPoint& aDestOffset, 1229 const DrawOptions& aOptions, 1230 const StrokeOptions* aStrokeOptions) 1231 : RecordedEventDerived(DEFERFILTERINPUT), 1232 mRefPtr(aRefPtr), 1233 mPath(aPath), 1234 mPattern(), 1235 mSourceRect(aSourceRect), 1236 mDestOffset(aDestOffset), 1237 mOptions(aOptions), 1238 mHasStrokeOptions(!!aStrokeOptions), 1239 mStrokeOptions(aStrokeOptions ? *aStrokeOptions : StrokeOptions()) { 1240 StorePattern(mPattern, aPattern); 1241 } 1242 1243 bool PlayEvent(Translator* aTranslator) const override; 1244 1245 template <class S> 1246 void Record(S& aStream) const; 1247 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1248 1249 std::string GetName() const override { return "DeferFilterInput"; } 1250 1251 private: 1252 friend class RecordedEvent; 1253 1254 template <class S> 1255 MOZ_IMPLICIT RecordedDeferFilterInput(S& aStream); 1256 1257 ReferencePtr mRefPtr; 1258 ReferencePtr mPath; 1259 PatternStorage mPattern; 1260 IntRect mSourceRect; 1261 IntPoint mDestOffset; 1262 DrawOptions mOptions; 1263 bool mHasStrokeOptions = false; 1264 StrokeOptions mStrokeOptions; 1265 }; 1266 1267 class RecordedFilterNodeDestruction 1268 : public RecordedEventDerived<RecordedFilterNodeDestruction> { 1269 public: 1270 MOZ_IMPLICIT RecordedFilterNodeDestruction(ReferencePtr aRefPtr) 1271 : RecordedEventDerived(FILTERNODEDESTRUCTION), mRefPtr(aRefPtr) {} 1272 1273 bool PlayEvent(Translator* aTranslator) const override; 1274 1275 template <class S> 1276 void Record(S& aStream) const; 1277 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1278 1279 std::string GetName() const override { return "FilterNode Destruction"; } 1280 1281 private: 1282 friend class RecordedEvent; 1283 1284 ReferencePtr mRefPtr; 1285 1286 template <class S> 1287 MOZ_IMPLICIT RecordedFilterNodeDestruction(S& aStream); 1288 }; 1289 1290 class RecordedGradientStopsCreation 1291 : public RecordedEventDerived<RecordedGradientStopsCreation> { 1292 public: 1293 RecordedGradientStopsCreation(ReferencePtr aRefPtr, GradientStop* aStops, 1294 uint32_t aNumStops, ExtendMode aExtendMode) 1295 : RecordedEventDerived(GRADIENTSTOPSCREATION), 1296 mRefPtr(aRefPtr), 1297 mStops(aStops), 1298 mNumStops(aNumStops), 1299 mExtendMode(aExtendMode), 1300 mDataOwned(false) {} 1301 1302 ~RecordedGradientStopsCreation(); 1303 1304 bool PlayEvent(Translator* aTranslator) const override; 1305 1306 template <class S> 1307 void Record(S& aStream) const; 1308 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1309 1310 std::string GetName() const override { return "GradientStops Creation"; } 1311 1312 private: 1313 friend class RecordedEvent; 1314 1315 ReferencePtr mRefPtr; 1316 GradientStop* mStops = nullptr; 1317 uint32_t mNumStops = 0; 1318 ExtendMode mExtendMode; 1319 bool mDataOwned; 1320 1321 template <class S> 1322 MOZ_IMPLICIT RecordedGradientStopsCreation(S& aStream); 1323 }; 1324 1325 class RecordedGradientStopsDestruction 1326 : public RecordedEventDerived<RecordedGradientStopsDestruction> { 1327 public: 1328 MOZ_IMPLICIT RecordedGradientStopsDestruction(ReferencePtr aRefPtr) 1329 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION), mRefPtr(aRefPtr) {} 1330 1331 bool PlayEvent(Translator* aTranslator) const override; 1332 1333 template <class S> 1334 void Record(S& aStream) const; 1335 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1336 1337 std::string GetName() const override { return "GradientStops Destruction"; } 1338 1339 private: 1340 friend class RecordedEvent; 1341 1342 ReferencePtr mRefPtr; 1343 1344 template <class S> 1345 MOZ_IMPLICIT RecordedGradientStopsDestruction(S& aStream); 1346 }; 1347 1348 class RecordedFlush : public RecordedEventDerived<RecordedFlush> { 1349 public: 1350 explicit RecordedFlush() : RecordedEventDerived(FLUSH) {} 1351 1352 bool PlayEvent(Translator* aTranslator) const final; 1353 1354 template <class S> 1355 void Record(S& aStream) const; 1356 virtual void OutputSimpleEventInfo( 1357 std::stringstream& aStringStream) const override; 1358 1359 virtual std::string GetName() const override { return "Flush"; } 1360 1361 private: 1362 friend class RecordedEvent; 1363 1364 template <class S> 1365 MOZ_IMPLICIT RecordedFlush(S& aStream); 1366 }; 1367 1368 class RecordedDetachAllSnapshots 1369 : public RecordedEventDerived<RecordedDetachAllSnapshots> { 1370 public: 1371 explicit RecordedDetachAllSnapshots() 1372 : RecordedEventDerived(DETACHALLSNAPSHOTS) {} 1373 1374 bool PlayEvent(Translator* aTranslator) const final; 1375 1376 template <class S> 1377 void Record(S& aStream) const; 1378 virtual void OutputSimpleEventInfo( 1379 std::stringstream& aStringStream) const override; 1380 1381 virtual std::string GetName() const override { return "DetachAllSnapshots"; } 1382 1383 private: 1384 friend class RecordedEvent; 1385 1386 template <class S> 1387 MOZ_IMPLICIT RecordedDetachAllSnapshots(S& aStream); 1388 }; 1389 1390 class RecordedSnapshot : public RecordedEventDerived<RecordedSnapshot> { 1391 public: 1392 explicit RecordedSnapshot(ReferencePtr aRefPtr) 1393 : RecordedEventDerived(SNAPSHOT), mRefPtr(aRefPtr) {} 1394 1395 bool PlayEvent(Translator* aTranslator) const override; 1396 1397 template <class S> 1398 void Record(S& aStream) const; 1399 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1400 1401 std::string GetName() const override { return "Snapshot"; } 1402 1403 private: 1404 friend class RecordedEvent; 1405 1406 ReferencePtr mRefPtr; 1407 1408 template <class S> 1409 MOZ_IMPLICIT RecordedSnapshot(S& aStream); 1410 }; 1411 1412 class RecordedIntoLuminanceSource 1413 : public RecordedEventDerived<RecordedIntoLuminanceSource> { 1414 public: 1415 RecordedIntoLuminanceSource(ReferencePtr aRefPtr, 1416 LuminanceType aLuminanceType, float aOpacity) 1417 : RecordedEventDerived(INTOLUMINANCE), 1418 mRefPtr(aRefPtr), 1419 mLuminanceType(aLuminanceType), 1420 mOpacity(aOpacity) {} 1421 1422 bool PlayEvent(Translator* aTranslator) const override; 1423 1424 template <class S> 1425 void Record(S& aStream) const; 1426 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1427 1428 std::string GetName() const override { return "IntoLuminanceSource"; } 1429 1430 private: 1431 friend class RecordedEvent; 1432 1433 ReferencePtr mRefPtr; 1434 LuminanceType mLuminanceType; 1435 float mOpacity; 1436 1437 template <class S> 1438 MOZ_IMPLICIT RecordedIntoLuminanceSource(S& aStream); 1439 }; 1440 1441 class RecordedExtractSubrect 1442 : public RecordedEventDerived<RecordedExtractSubrect> { 1443 public: 1444 RecordedExtractSubrect(ReferencePtr aRefPtr, ReferencePtr aSourceSurface, 1445 const IntRect& aSubrect) 1446 : RecordedEventDerived(EXTRACTSUBRECT), 1447 mRefPtr(aRefPtr), 1448 mSourceSurface(aSourceSurface), 1449 mSubrect(aSubrect) {} 1450 1451 bool PlayEvent(Translator* aTranslator) const override; 1452 1453 template <class S> 1454 void Record(S& aStream) const; 1455 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1456 1457 std::string GetName() const override { return "ExtractSubrect"; } 1458 1459 private: 1460 friend class RecordedEvent; 1461 1462 ReferencePtr mRefPtr; 1463 ReferencePtr mSourceSurface; 1464 IntRect mSubrect; 1465 1466 template <class S> 1467 MOZ_IMPLICIT RecordedExtractSubrect(S& aStream); 1468 }; 1469 1470 class RecordedFontData : public RecordedEventDerived<RecordedFontData> { 1471 public: 1472 static void FontDataProc(const uint8_t* aData, uint32_t aSize, 1473 uint32_t aIndex, void* aBaton) { 1474 auto recordedFontData = static_cast<RecordedFontData*>(aBaton); 1475 recordedFontData->SetFontData(aData, aSize, aIndex); 1476 } 1477 1478 explicit RecordedFontData(UnscaledFont* aUnscaledFont) 1479 : RecordedEventDerived(FONTDATA), 1480 mType(aUnscaledFont->GetType()), 1481 mFontDetails() { 1482 if (!aUnscaledFont->GetFontFileData(&FontDataProc, this)) { 1483 mGetFontFileDataSucceeded = false; 1484 } 1485 } 1486 1487 bool IsValid() const { return mGetFontFileDataSucceeded; } 1488 1489 bool PlayEvent(Translator* aTranslator) const override; 1490 1491 template <class S> 1492 void Record(S& aStream) const; 1493 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1494 1495 std::string GetName() const override { return "Font Data"; } 1496 1497 void SetFontData(const uint8_t* aData, uint32_t aSize, uint32_t aIndex); 1498 1499 bool GetFontDetails(RecordedFontDetails& fontDetails); 1500 1501 private: 1502 friend class RecordedEvent; 1503 1504 FontType mType; 1505 RecordedEventArray<uint8_t, uint32_t> mData; 1506 RecordedFontDetails mFontDetails; 1507 1508 bool mGetFontFileDataSucceeded = true; 1509 1510 template <class S> 1511 MOZ_IMPLICIT RecordedFontData(S& aStream); 1512 }; 1513 1514 class RecordedFontDescriptor 1515 : public RecordedEventDerived<RecordedFontDescriptor> { 1516 public: 1517 static void FontDescCb(const uint8_t* aData, uint32_t aSize, uint32_t aIndex, 1518 void* aBaton) { 1519 auto recordedFontDesc = static_cast<RecordedFontDescriptor*>(aBaton); 1520 recordedFontDesc->SetFontDescriptor(aData, aSize, aIndex); 1521 } 1522 1523 explicit RecordedFontDescriptor(UnscaledFont* aUnscaledFont) 1524 : RecordedEventDerived(FONTDESC), 1525 mType(aUnscaledFont->GetType()), 1526 mIndex(0), 1527 mRefPtr(aUnscaledFont) { 1528 mHasDesc = aUnscaledFont->GetFontDescriptor(FontDescCb, this); 1529 } 1530 1531 virtual ~RecordedFontDescriptor(); 1532 1533 bool IsValid() const { return mHasDesc; } 1534 1535 bool PlayEvent(Translator* aTranslator) const override; 1536 1537 template <class S> 1538 void Record(S& aStream) const; 1539 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1540 1541 std::string GetName() const override { return "Font Desc"; } 1542 1543 private: 1544 friend class RecordedEvent; 1545 1546 void SetFontDescriptor(const uint8_t* aData, uint32_t aSize, uint32_t aIndex); 1547 1548 bool mHasDesc; 1549 1550 FontType mType; 1551 RecordedEventArray<uint8_t> mData; 1552 uint32_t mIndex; 1553 ReferencePtr mRefPtr; 1554 1555 template <class S> 1556 MOZ_IMPLICIT RecordedFontDescriptor(S& aStream); 1557 }; 1558 1559 class RecordedUnscaledFontCreation 1560 : public RecordedEventDerived<RecordedUnscaledFontCreation> { 1561 public: 1562 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize, 1563 void* aBaton) { 1564 auto recordedUnscaledFontCreation = 1565 static_cast<RecordedUnscaledFontCreation*>(aBaton); 1566 recordedUnscaledFontCreation->SetFontInstanceData(aData, aSize); 1567 } 1568 1569 RecordedUnscaledFontCreation(UnscaledFont* aUnscaledFont, 1570 RecordedFontDetails aFontDetails) 1571 : RecordedEventDerived(UNSCALEDFONTCREATION), 1572 mRefPtr(aUnscaledFont), 1573 mFontDataKey(aFontDetails.fontDataKey), 1574 mIndex(aFontDetails.index) { 1575 aUnscaledFont->GetFontInstanceData(FontInstanceDataProc, this); 1576 } 1577 1578 bool PlayEvent(Translator* aTranslator) const override; 1579 1580 template <class S> 1581 void Record(S& aStream) const; 1582 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1583 1584 std::string GetName() const override { return "UnscaledFont Creation"; } 1585 1586 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize); 1587 1588 private: 1589 friend class RecordedEvent; 1590 1591 ReferencePtr mRefPtr; 1592 uint64_t mFontDataKey; 1593 uint32_t mIndex; 1594 RecordedEventArray<uint8_t> mInstanceData; 1595 1596 template <class S> 1597 MOZ_IMPLICIT RecordedUnscaledFontCreation(S& aStream); 1598 }; 1599 1600 class RecordedUnscaledFontDestruction 1601 : public RecordedEventDerived<RecordedUnscaledFontDestruction> { 1602 public: 1603 MOZ_IMPLICIT RecordedUnscaledFontDestruction(ReferencePtr aRefPtr) 1604 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {} 1605 1606 bool PlayEvent(Translator* aTranslator) const override; 1607 template <class S> 1608 void Record(S& aStream) const; 1609 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1610 1611 std::string GetName() const override { return "UnscaledFont Destruction"; } 1612 1613 private: 1614 friend class RecordedEvent; 1615 1616 ReferencePtr mRefPtr; 1617 1618 template <class S> 1619 MOZ_IMPLICIT RecordedUnscaledFontDestruction(S& aStream); 1620 }; 1621 1622 class RecordedScaledFontCreation 1623 : public RecordedEventDerived<RecordedScaledFontCreation> { 1624 public: 1625 static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize, 1626 const FontVariation* aVariations, 1627 uint32_t aNumVariations, void* aBaton) { 1628 auto recordedScaledFontCreation = 1629 static_cast<RecordedScaledFontCreation*>(aBaton); 1630 recordedScaledFontCreation->SetFontInstanceData(aData, aSize, aVariations, 1631 aNumVariations); 1632 } 1633 1634 RecordedScaledFontCreation(ScaledFont* aScaledFont, 1635 UnscaledFont* aUnscaledFont) 1636 : RecordedEventDerived(SCALEDFONTCREATION), 1637 mRefPtr(aScaledFont), 1638 mUnscaledFont(aUnscaledFont), 1639 mGlyphSize(aScaledFont->GetSize()) { 1640 aScaledFont->GetFontInstanceData(FontInstanceDataProc, this); 1641 } 1642 1643 bool PlayEvent(Translator* aTranslator) const override; 1644 1645 template <class S> 1646 void Record(S& aStream) const; 1647 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1648 1649 std::string GetName() const override { return "ScaledFont Creation"; } 1650 1651 void SetFontInstanceData(const uint8_t* aData, uint32_t aSize, 1652 const FontVariation* aVariations, 1653 uint32_t aNumVariations); 1654 1655 private: 1656 friend class RecordedEvent; 1657 1658 ReferencePtr mRefPtr; 1659 ReferencePtr mUnscaledFont; 1660 Float mGlyphSize; 1661 RecordedEventArray<uint8_t> mInstanceData; 1662 RecordedEventArray<FontVariation> mVariations; 1663 1664 template <class S> 1665 MOZ_IMPLICIT RecordedScaledFontCreation(S& aStream); 1666 }; 1667 1668 class RecordedScaledFontDestruction 1669 : public RecordedEventDerived<RecordedScaledFontDestruction> { 1670 public: 1671 MOZ_IMPLICIT RecordedScaledFontDestruction(ReferencePtr aRefPtr) 1672 : RecordedEventDerived(SCALEDFONTDESTRUCTION), mRefPtr(aRefPtr) {} 1673 1674 bool PlayEvent(Translator* aTranslator) const override; 1675 1676 template <class S> 1677 void Record(S& aStream) const; 1678 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1679 1680 std::string GetName() const override { return "ScaledFont Destruction"; } 1681 1682 private: 1683 friend class RecordedEvent; 1684 1685 ReferencePtr mRefPtr; 1686 1687 template <class S> 1688 MOZ_IMPLICIT RecordedScaledFontDestruction(S& aStream); 1689 }; 1690 1691 class RecordedMaskSurface : public RecordedEventDerived<RecordedMaskSurface> { 1692 public: 1693 RecordedMaskSurface(const Pattern& aPattern, ReferencePtr aRefMask, 1694 const Point& aOffset, const DrawOptions& aOptions) 1695 : RecordedEventDerived(MASKSURFACE), 1696 mPattern(), 1697 mRefMask(aRefMask), 1698 mOffset(aOffset), 1699 mOptions(aOptions) { 1700 StorePattern(mPattern, aPattern); 1701 } 1702 1703 bool PlayEvent(Translator* aTranslator) const override; 1704 1705 template <class S> 1706 void Record(S& aStream) const; 1707 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1708 1709 std::string GetName() const override { return "MaskSurface"; } 1710 1711 private: 1712 friend class RecordedEvent; 1713 1714 template <class S> 1715 MOZ_IMPLICIT RecordedMaskSurface(S& aStream); 1716 1717 PatternStorage mPattern; 1718 ReferencePtr mRefMask; 1719 Point mOffset; 1720 DrawOptions mOptions; 1721 }; 1722 1723 class RecordedFilterNodeSetAttribute 1724 : public RecordedEventDerived<RecordedFilterNodeSetAttribute> { 1725 public: 1726 enum ArgType { 1727 ARGTYPE_UINT32, 1728 ARGTYPE_BOOL, 1729 ARGTYPE_FLOAT, 1730 ARGTYPE_SIZE, 1731 ARGTYPE_INTSIZE, 1732 ARGTYPE_INTPOINT, 1733 ARGTYPE_RECT, 1734 ARGTYPE_INTRECT, 1735 ARGTYPE_POINT, 1736 ARGTYPE_MATRIX, 1737 ARGTYPE_MATRIX5X4, 1738 ARGTYPE_POINT3D, 1739 ARGTYPE_COLOR, 1740 ARGTYPE_FLOAT_ARRAY 1741 }; 1742 1743 template <typename T> 1744 void WritePayload(const T& aValue) { 1745 mPayload.Assign(reinterpret_cast<const uint8_t*>(&aValue), sizeof(T)); 1746 } 1747 1748 void WritePayload(const bool& aValue) { 1749 uint8_t data = aValue ? 1 : 0; 1750 mPayload.Assign(&data, 1); 1751 } 1752 1753 template <typename T> 1754 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex, 1755 T aArgument, ArgType aArgType) 1756 : RecordedEventDerived(FILTERNODESETATTRIBUTE), 1757 mNode(aNode), 1758 mIndex(aIndex), 1759 mArgType(aArgType) { 1760 WritePayload(aArgument); 1761 } 1762 1763 RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex, 1764 const Float* aFloat, uint32_t aSize) 1765 : RecordedEventDerived(FILTERNODESETATTRIBUTE), 1766 mNode(aNode), 1767 mIndex(aIndex), 1768 mArgType(ARGTYPE_FLOAT_ARRAY) { 1769 mPayload.Assign(reinterpret_cast<const uint8_t*>(aFloat), 1770 sizeof(Float) * aSize); 1771 } 1772 1773 bool PlayEvent(Translator* aTranslator) const override; 1774 template <class S> 1775 void Record(S& aStream) const; 1776 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1777 1778 std::string GetName() const override { return "SetAttribute"; } 1779 1780 private: 1781 friend class RecordedEvent; 1782 1783 ReferencePtr mNode; 1784 1785 uint32_t mIndex; 1786 ArgType mArgType; 1787 RecordedEventArray<uint8_t> mPayload; 1788 1789 template <class S> 1790 MOZ_IMPLICIT RecordedFilterNodeSetAttribute(S& aStream); 1791 }; 1792 1793 class RecordedFilterNodeSetInput 1794 : public RecordedEventDerived<RecordedFilterNodeSetInput> { 1795 public: 1796 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex, 1797 FilterNode* aInputNode) 1798 : RecordedEventDerived(FILTERNODESETINPUT), 1799 mNode(aNode), 1800 mIndex(aIndex), 1801 mInputFilter(aInputNode), 1802 mInputSurface(nullptr) {} 1803 1804 RecordedFilterNodeSetInput(FilterNode* aNode, uint32_t aIndex, 1805 SourceSurface* aInputSurface) 1806 : RecordedEventDerived(FILTERNODESETINPUT), 1807 mNode(aNode), 1808 mIndex(aIndex), 1809 mInputFilter(nullptr), 1810 mInputSurface(aInputSurface) {} 1811 1812 bool PlayEvent(Translator* aTranslator) const override; 1813 template <class S> 1814 void Record(S& aStream) const; 1815 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1816 1817 std::string GetName() const override { return "SetInput"; } 1818 1819 private: 1820 friend class RecordedEvent; 1821 1822 ReferencePtr mNode; 1823 uint32_t mIndex; 1824 ReferencePtr mInputFilter; 1825 ReferencePtr mInputSurface; 1826 1827 template <class S> 1828 MOZ_IMPLICIT RecordedFilterNodeSetInput(S& aStream); 1829 }; 1830 1831 class RecordedLink : public RecordedEventDerived<RecordedLink> { 1832 public: 1833 RecordedLink(const char* aLocalDest, const char* aURI, const Rect& aRect) 1834 : RecordedEventDerived(LINK), 1835 mLocalDest(aLocalDest), 1836 mURI(aURI), 1837 mRect(aRect) {} 1838 1839 bool PlayEvent(Translator* aTranslator) const override; 1840 template <class S> 1841 void Record(S& aStream) const; 1842 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1843 1844 std::string GetName() const override { return "Link"; } 1845 1846 private: 1847 friend class RecordedEvent; 1848 1849 RecordedEventCString mLocalDest; 1850 RecordedEventCString mURI; 1851 Rect mRect; 1852 1853 template <class S> 1854 MOZ_IMPLICIT RecordedLink(S& aStream); 1855 }; 1856 1857 class RecordedDestination : public RecordedEventDerived<RecordedDestination> { 1858 public: 1859 RecordedDestination(const char* aDestination, const Point& aPoint) 1860 : RecordedEventDerived(DESTINATION), 1861 mDestination(aDestination), 1862 mPoint(aPoint) {} 1863 1864 bool PlayEvent(Translator* aTranslator) const override; 1865 template <class S> 1866 void Record(S& aStream) const; 1867 void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; 1868 1869 std::string GetName() const override { return "Destination"; } 1870 1871 private: 1872 friend class RecordedEvent; 1873 1874 RecordedEventCString mDestination; 1875 Point mPoint; 1876 1877 template <class S> 1878 MOZ_IMPLICIT RecordedDestination(S& aStream); 1879 }; 1880 1881 static std::string NameFromBackend(BackendType aType) { 1882 switch (aType) { 1883 case BackendType::NONE: 1884 return "None"; 1885 default: 1886 return "Unknown"; 1887 } 1888 } 1889 1890 template <class S> 1891 void RecordedEvent::RecordPatternData(S& aStream, 1892 const PatternStorage& aPattern) const { 1893 WriteElement(aStream, aPattern.mType); 1894 1895 switch (aPattern.mType) { 1896 case PatternType::COLOR: { 1897 WriteElement(aStream, *reinterpret_cast<const ColorPatternStorage*>( 1898 &aPattern.mStorage)); 1899 return; 1900 } 1901 case PatternType::LINEAR_GRADIENT: { 1902 WriteElement(aStream, 1903 *reinterpret_cast<const LinearGradientPatternStorage*>( 1904 &aPattern.mStorage)); 1905 return; 1906 } 1907 case PatternType::RADIAL_GRADIENT: { 1908 WriteElement(aStream, 1909 *reinterpret_cast<const RadialGradientPatternStorage*>( 1910 &aPattern.mStorage)); 1911 return; 1912 } 1913 case PatternType::CONIC_GRADIENT: { 1914 WriteElement(aStream, 1915 *reinterpret_cast<const ConicGradientPatternStorage*>( 1916 &aPattern.mStorage)); 1917 return; 1918 } 1919 case PatternType::SURFACE: { 1920 WriteElement(aStream, *reinterpret_cast<const SurfacePatternStorage*>( 1921 &aPattern.mStorage)); 1922 return; 1923 } 1924 default: 1925 return; 1926 } 1927 } 1928 1929 template <class S> 1930 void RecordedEvent::ReadPatternData(S& aStream, 1931 PatternStorage& aPattern) const { 1932 ReadElementConstrained(aStream, aPattern.mType, PatternType::COLOR, 1933 kHighestPatternType); 1934 1935 switch (aPattern.mType) { 1936 case PatternType::COLOR: { 1937 ReadElement(aStream, 1938 *reinterpret_cast<ColorPatternStorage*>(&aPattern.mStorage)); 1939 return; 1940 } 1941 case PatternType::LINEAR_GRADIENT: { 1942 ReadElement(aStream, *reinterpret_cast<LinearGradientPatternStorage*>( 1943 &aPattern.mStorage)); 1944 return; 1945 } 1946 case PatternType::RADIAL_GRADIENT: { 1947 ReadElement(aStream, *reinterpret_cast<RadialGradientPatternStorage*>( 1948 &aPattern.mStorage)); 1949 return; 1950 } 1951 case PatternType::CONIC_GRADIENT: { 1952 ReadElement(aStream, *reinterpret_cast<ConicGradientPatternStorage*>( 1953 &aPattern.mStorage)); 1954 return; 1955 } 1956 case PatternType::SURFACE: { 1957 SurfacePatternStorage* sps = 1958 reinterpret_cast<SurfacePatternStorage*>(&aPattern.mStorage); 1959 ReadElement(aStream, *sps); 1960 if (sps->mExtend < ExtendMode::CLAMP || 1961 sps->mExtend > ExtendMode::REFLECT) { 1962 aStream.SetIsBad(); 1963 return; 1964 } 1965 1966 if (sps->mSamplingFilter < SamplingFilter::GOOD || 1967 sps->mSamplingFilter >= SamplingFilter::SENTINEL) { 1968 aStream.SetIsBad(); 1969 } 1970 return; 1971 } 1972 default: 1973 return; 1974 } 1975 } 1976 1977 inline void RecordedEvent::StorePattern(PatternStorage& aDestination, 1978 const Pattern& aSource) const { 1979 aDestination.mType = aSource.GetType(); 1980 1981 switch (aSource.GetType()) { 1982 case PatternType::COLOR: { 1983 reinterpret_cast<ColorPatternStorage*>(&aDestination.mStorage)->mColor = 1984 static_cast<const ColorPattern*>(&aSource)->mColor; 1985 return; 1986 } 1987 case PatternType::LINEAR_GRADIENT: { 1988 LinearGradientPatternStorage* store = 1989 reinterpret_cast<LinearGradientPatternStorage*>( 1990 &aDestination.mStorage); 1991 const LinearGradientPattern* pat = 1992 static_cast<const LinearGradientPattern*>(&aSource); 1993 store->mBegin = pat->mBegin; 1994 store->mEnd = pat->mEnd; 1995 store->mMatrix = pat->mMatrix; 1996 store->mStops = pat->mStops.get(); 1997 return; 1998 } 1999 case PatternType::RADIAL_GRADIENT: { 2000 RadialGradientPatternStorage* store = 2001 reinterpret_cast<RadialGradientPatternStorage*>( 2002 &aDestination.mStorage); 2003 const RadialGradientPattern* pat = 2004 static_cast<const RadialGradientPattern*>(&aSource); 2005 store->mCenter1 = pat->mCenter1; 2006 store->mCenter2 = pat->mCenter2; 2007 store->mRadius1 = pat->mRadius1; 2008 store->mRadius2 = pat->mRadius2; 2009 store->mMatrix = pat->mMatrix; 2010 store->mStops = pat->mStops.get(); 2011 return; 2012 } 2013 case PatternType::CONIC_GRADIENT: { 2014 ConicGradientPatternStorage* store = 2015 reinterpret_cast<ConicGradientPatternStorage*>( 2016 &aDestination.mStorage); 2017 const ConicGradientPattern* pat = 2018 static_cast<const ConicGradientPattern*>(&aSource); 2019 store->mCenter = pat->mCenter; 2020 store->mAngle = pat->mAngle; 2021 store->mStartOffset = pat->mStartOffset; 2022 store->mEndOffset = pat->mEndOffset; 2023 store->mMatrix = pat->mMatrix; 2024 store->mStops = pat->mStops.get(); 2025 return; 2026 } 2027 case PatternType::SURFACE: { 2028 SurfacePatternStorage* store = 2029 reinterpret_cast<SurfacePatternStorage*>(&aDestination.mStorage); 2030 const SurfacePattern* pat = static_cast<const SurfacePattern*>(&aSource); 2031 store->mExtend = pat->mExtendMode; 2032 store->mSamplingFilter = pat->mSamplingFilter; 2033 store->mMatrix = pat->mMatrix; 2034 store->mSurface = pat->mSurface; 2035 store->mSamplingRect = pat->mSamplingRect; 2036 return; 2037 } 2038 } 2039 } 2040 2041 template <class S> 2042 void RecordedStrokeOptionsMixin::RecordStrokeOptions( 2043 S& aStream, const StrokeOptions& aStrokeOptions) const { 2044 JoinStyle joinStyle = aStrokeOptions.mLineJoin; 2045 CapStyle capStyle = aStrokeOptions.mLineCap; 2046 2047 WriteElement(aStream, uint64_t(aStrokeOptions.mDashLength)); 2048 WriteElement(aStream, aStrokeOptions.mLineWidth); 2049 WriteElement(aStream, aStrokeOptions.mMiterLimit); 2050 WriteElement(aStream, joinStyle); 2051 WriteElement(aStream, capStyle); 2052 2053 if (!aStrokeOptions.mDashPattern) { 2054 return; 2055 } 2056 2057 WriteElement(aStream, aStrokeOptions.mDashOffset); 2058 aStream.write((char*)aStrokeOptions.mDashPattern, 2059 sizeof(Float) * aStrokeOptions.mDashLength); 2060 } 2061 2062 template <class S> 2063 void RecordedStrokeOptionsMixin::ReadStrokeOptions( 2064 S& aStream, StrokeOptions& aStrokeOptions) { 2065 uint64_t dashLength64 = 0; 2066 JoinStyle joinStyle; 2067 CapStyle capStyle; 2068 2069 ReadElement(aStream, dashLength64); 2070 ReadElement(aStream, aStrokeOptions.mLineWidth); 2071 ReadElement(aStream, aStrokeOptions.mMiterLimit); 2072 ReadElementConstrained(aStream, joinStyle, JoinStyle::BEVEL, 2073 JoinStyle::MITER_OR_BEVEL); 2074 ReadElementConstrained(aStream, capStyle, CapStyle::BUTT, CapStyle::SQUARE); 2075 aStrokeOptions.mLineJoin = joinStyle; 2076 aStrokeOptions.mLineCap = capStyle; 2077 2078 // On 32 bit we truncate the value of dashLength. 2079 // See also bug 811850 for history. 2080 size_t dashLength = size_t(dashLength64); 2081 if (!dashLength || !aStream.good()) { 2082 return; 2083 } 2084 2085 ReadElement(aStream, aStrokeOptions.mDashOffset); 2086 2087 mDashPatternStorage = MakeUniqueFallible<Float[]>(dashLength); 2088 if (!mDashPatternStorage) { 2089 aStream.SetIsBad(); 2090 return; 2091 } 2092 aStream.read((char*)mDashPatternStorage.get(), sizeof(Float) * dashLength); 2093 if (!aStream.good()) { 2094 aStream.SetIsBad(); 2095 return; 2096 } 2097 aStrokeOptions.mDashLength = dashLength; 2098 aStrokeOptions.mDashPattern = mDashPatternStorage.get(); 2099 } 2100 2101 template <class S> 2102 static void ReadDrawOptions(S& aStream, DrawOptions& aDrawOptions) { 2103 ReadElement(aStream, aDrawOptions); 2104 if (aDrawOptions.mAntialiasMode < AntialiasMode::NONE || 2105 aDrawOptions.mAntialiasMode > AntialiasMode::DEFAULT) { 2106 aStream.SetIsBad(); 2107 return; 2108 } 2109 2110 if (aDrawOptions.mCompositionOp < CompositionOp::OP_CLEAR || 2111 aDrawOptions.mCompositionOp > CompositionOp::OP_COUNT) { 2112 aStream.SetIsBad(); 2113 } 2114 } 2115 2116 template <class S> 2117 static void ReadDrawSurfaceOptions(S& aStream, 2118 DrawSurfaceOptions& aDrawSurfaceOptions) { 2119 ReadElement(aStream, aDrawSurfaceOptions); 2120 if (aDrawSurfaceOptions.mSamplingFilter < SamplingFilter::GOOD || 2121 aDrawSurfaceOptions.mSamplingFilter >= SamplingFilter::SENTINEL) { 2122 aStream.SetIsBad(); 2123 return; 2124 } 2125 2126 if (aDrawSurfaceOptions.mSamplingBounds < SamplingBounds::UNBOUNDED || 2127 aDrawSurfaceOptions.mSamplingBounds > SamplingBounds::BOUNDED) { 2128 aStream.SetIsBad(); 2129 } 2130 } 2131 2132 inline void RecordedEvent::OutputSimplePatternInfo( 2133 const PatternStorage& aStorage, std::stringstream& aOutput) const { 2134 switch (aStorage.mType) { 2135 case PatternType::COLOR: { 2136 const DeviceColor color = 2137 reinterpret_cast<const ColorPatternStorage*>(&aStorage.mStorage) 2138 ->mColor; 2139 aOutput << "DeviceColor: (" << color.r << ", " << color.g << ", " 2140 << color.b << ", " << color.a << ")"; 2141 return; 2142 } 2143 case PatternType::LINEAR_GRADIENT: { 2144 const LinearGradientPatternStorage* store = 2145 reinterpret_cast<const LinearGradientPatternStorage*>( 2146 &aStorage.mStorage); 2147 2148 aOutput << "LinearGradient (" << store->mBegin.x << ", " 2149 << store->mBegin.y << ") - (" << store->mEnd.x << ", " 2150 << store->mEnd.y << ") Stops: " << store->mStops; 2151 return; 2152 } 2153 case PatternType::RADIAL_GRADIENT: { 2154 const RadialGradientPatternStorage* store = 2155 reinterpret_cast<const RadialGradientPatternStorage*>( 2156 &aStorage.mStorage); 2157 aOutput << "RadialGradient (Center 1: (" << store->mCenter1.x << ", " 2158 << store->mCenter2.y << ") Radius 2: " << store->mRadius2; 2159 return; 2160 } 2161 case PatternType::CONIC_GRADIENT: { 2162 const ConicGradientPatternStorage* store = 2163 reinterpret_cast<const ConicGradientPatternStorage*>( 2164 &aStorage.mStorage); 2165 aOutput << "ConicGradient (Center: (" << store->mCenter.x << ", " 2166 << store->mCenter.y << ") Angle: " << store->mAngle 2167 << " Range:" << store->mStartOffset << " - " << store->mEndOffset; 2168 return; 2169 } 2170 case PatternType::SURFACE: { 2171 const SurfacePatternStorage* store = 2172 reinterpret_cast<const SurfacePatternStorage*>(&aStorage.mStorage); 2173 aOutput << "Surface (0x" << store->mSurface << ")"; 2174 return; 2175 } 2176 } 2177 } 2178 2179 inline bool RecordedDrawTargetCreation::PlayEvent( 2180 Translator* aTranslator) const { 2181 RefPtr<DrawTarget> newDT = 2182 aTranslator->CreateDrawTarget(mRefPtr, mRect.Size(), mFormat); 2183 2184 // If we couldn't create a DrawTarget this will probably cause us to crash 2185 // with nullptr later in the playback, so return false to abort. 2186 if (!newDT) { 2187 return false; 2188 } 2189 2190 if (mHasExistingData) { 2191 Rect dataRect(0, 0, mExistingData->GetSize().width, 2192 mExistingData->GetSize().height); 2193 newDT->DrawSurface(mExistingData, dataRect, dataRect); 2194 } 2195 2196 return true; 2197 } 2198 2199 template <class S> 2200 void RecordedDrawTargetCreation::Record(S& aStream) const { 2201 WriteElement(aStream, mRefPtr); 2202 WriteElement(aStream, mBackendType); 2203 WriteElement(aStream, mRect); 2204 WriteElement(aStream, mFormat); 2205 WriteElement(aStream, mHasExistingData); 2206 2207 if (mHasExistingData) { 2208 MOZ_ASSERT(mExistingData); 2209 MOZ_ASSERT(mExistingData->GetSize() == mRect.Size()); 2210 RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface(); 2211 2212 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ); 2213 for (int y = 0; y < mRect.height; y++) { 2214 aStream.write((const char*)map.GetData() + y * map.GetStride(), 2215 BytesPerPixel(mFormat) * mRect.width); 2216 } 2217 } 2218 } 2219 2220 template <class S> 2221 RecordedDrawTargetCreation::RecordedDrawTargetCreation(S& aStream) 2222 : RecordedEventDerived(DRAWTARGETCREATION), mExistingData(nullptr) { 2223 ReadElement(aStream, mRefPtr); 2224 ReadElementConstrained(aStream, mBackendType, BackendType::NONE, 2225 BackendType::WEBRENDER_TEXT); 2226 ReadElement(aStream, mRect); 2227 ReadElementConstrained(aStream, mFormat, SurfaceFormat::B8G8R8A8, 2228 SurfaceFormat::UNKNOWN); 2229 ReadElement(aStream, mHasExistingData); 2230 2231 if (mHasExistingData) { 2232 RefPtr<DataSourceSurface> dataSurf = 2233 Factory::CreateDataSourceSurface(mRect.Size(), mFormat); 2234 if (!dataSurf) { 2235 gfxWarning() 2236 << "RecordedDrawTargetCreation had to reset mHasExistingData"; 2237 mHasExistingData = false; 2238 return; 2239 } 2240 2241 DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ); 2242 for (int y = 0; y < mRect.height; y++) { 2243 aStream.read((char*)map.GetData() + y * map.GetStride(), 2244 BytesPerPixel(mFormat) * mRect.width); 2245 } 2246 mExistingData = dataSurf; 2247 } 2248 } 2249 2250 inline void RecordedDrawTargetCreation::OutputSimpleEventInfo( 2251 std::stringstream& aStringStream) const { 2252 aStringStream << "[" << mRefPtr << "] DrawTarget Creation (Type: " 2253 << NameFromBackend(mBackendType) << ", Size: " << mRect.width 2254 << "x" << mRect.height << ")"; 2255 } 2256 2257 inline bool RecordedDrawTargetDestruction::PlayEvent( 2258 Translator* aTranslator) const { 2259 aTranslator->RemoveDrawTarget(mRefPtr); 2260 return true; 2261 } 2262 2263 template <class S> 2264 void RecordedDrawTargetDestruction::Record(S& aStream) const { 2265 WriteElement(aStream, mRefPtr); 2266 } 2267 2268 template <class S> 2269 RecordedDrawTargetDestruction::RecordedDrawTargetDestruction(S& aStream) 2270 : RecordedEventDerived(DRAWTARGETDESTRUCTION) { 2271 ReadElement(aStream, mRefPtr); 2272 } 2273 2274 inline void RecordedDrawTargetDestruction::OutputSimpleEventInfo( 2275 std::stringstream& aStringStream) const { 2276 aStringStream << "[" << mRefPtr << "] DrawTarget Destruction"; 2277 } 2278 2279 inline bool RecordedSetCurrentDrawTarget::PlayEvent( 2280 Translator* aTranslator) const { 2281 return aTranslator->SetCurrentDrawTarget(mRefPtr); 2282 } 2283 2284 template <class S> 2285 void RecordedSetCurrentDrawTarget::Record(S& aStream) const { 2286 WriteElement(aStream, mRefPtr); 2287 } 2288 2289 template <class S> 2290 RecordedSetCurrentDrawTarget::RecordedSetCurrentDrawTarget(S& aStream) 2291 : RecordedEventDerived(SETCURRENTDRAWTARGET) { 2292 ReadElement(aStream, mRefPtr); 2293 } 2294 2295 inline void RecordedSetCurrentDrawTarget::OutputSimpleEventInfo( 2296 std::stringstream& aStringStream) const { 2297 aStringStream << "[" << mRefPtr << "] SetCurrentDrawTarget"; 2298 } 2299 2300 inline bool RecordedCreateSimilarDrawTarget::PlayEvent( 2301 Translator* aTranslator) const { 2302 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget(); 2303 if (!drawTarget) { 2304 return false; 2305 } 2306 2307 RefPtr<DrawTarget> newDT = 2308 drawTarget->CreateSimilarDrawTarget(mSize, mFormat); 2309 2310 // If we couldn't create a DrawTarget this will probably cause us to crash 2311 // with nullptr later in the playback, so return false to abort. 2312 if (!newDT) { 2313 return false; 2314 } 2315 2316 aTranslator->AddDrawTarget(mRefPtr, newDT); 2317 return true; 2318 } 2319 2320 template <class S> 2321 void RecordedCreateSimilarDrawTarget::Record(S& aStream) const { 2322 WriteElement(aStream, mRefPtr); 2323 WriteElement(aStream, mSize); 2324 WriteElement(aStream, mFormat); 2325 } 2326 2327 template <class S> 2328 RecordedCreateSimilarDrawTarget::RecordedCreateSimilarDrawTarget(S& aStream) 2329 : RecordedEventDerived(CREATESIMILARDRAWTARGET) { 2330 ReadElement(aStream, mRefPtr); 2331 ReadElement(aStream, mSize); 2332 ReadElementConstrained(aStream, mFormat, SurfaceFormat::B8G8R8A8, 2333 SurfaceFormat::UNKNOWN); 2334 } 2335 2336 inline void RecordedCreateSimilarDrawTarget::OutputSimpleEventInfo( 2337 std::stringstream& aStringStream) const { 2338 aStringStream << "[" << mRefPtr 2339 << "] CreateSimilarDrawTarget (Size: " << mSize.width << "x" 2340 << mSize.height << ")"; 2341 } 2342 2343 inline bool RecordedCreateDrawTargetForFilter::PlayEvent( 2344 Translator* aTranslator) const { 2345 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2346 if (!dt) { 2347 return false; 2348 } 2349 2350 IntRect baseRect = dt->GetRect(); 2351 2352 auto maxRect = IntRect(IntPoint(0, 0), mMaxSize); 2353 2354 auto clone = dt->GetTransform(); 2355 bool invertible = clone.Invert(); 2356 // mSourceRect is in filter space. The filter outputs from mSourceRect need 2357 // to be drawn at mDestPoint in user space. 2358 Rect userSpaceSource = Rect(mDestPoint, mSourceRect.Size()); 2359 if (invertible) { 2360 // Try to reduce the source rect so that it's not much bigger 2361 // than the draw target. The result is not minimal. Examples 2362 // are left as an exercise for the reader. 2363 auto destRect = IntRectToRect(baseRect); 2364 Rect userSpaceBounds = clone.TransformBounds(destRect); 2365 userSpaceSource = userSpaceSource.Intersect(userSpaceBounds); 2366 } 2367 2368 // Compute how much we moved the top-left of the source rect by, and use that 2369 // to compute the new dest point, and move our intersected source rect back 2370 // into the (new) filter space. 2371 Point shift = userSpaceSource.TopLeft() - mDestPoint; 2372 Rect filterSpaceSource = 2373 Rect(mSourceRect.TopLeft() + shift, userSpaceSource.Size()); 2374 2375 baseRect = RoundedOut(filterSpaceSource); 2376 FilterNode* filter = aTranslator->LookupFilterNode(mFilter); 2377 if (!filter) { 2378 return false; 2379 } 2380 2381 IntRect transformedRect = filter->MapRectToSource( 2382 baseRect, maxRect, aTranslator->LookupFilterNode(mSource)); 2383 2384 // Intersect with maxRect to make sure we didn't end up with something bigger 2385 transformedRect = transformedRect.Intersect(maxRect); 2386 2387 // If we end up with an empty rect make it 1x1 so that things don't break. 2388 if (transformedRect.IsEmpty()) { 2389 transformedRect = IntRect(0, 0, 1, 1); 2390 } 2391 2392 RefPtr<DrawTarget> newDT = 2393 dt->CreateSimilarDrawTarget(transformedRect.Size(), mFormat); 2394 if (!newDT) { 2395 return false; 2396 } 2397 newDT = 2398 gfx::Factory::CreateOffsetDrawTarget(newDT, transformedRect.TopLeft()); 2399 2400 // If we couldn't create a DrawTarget this will probably cause us to crash 2401 // with nullptr later in the playback, so return false to abort. 2402 if (!newDT) { 2403 return false; 2404 } 2405 2406 aTranslator->AddDrawTarget(mRefPtr, newDT); 2407 return true; 2408 } 2409 2410 inline bool RecordedCreateClippedDrawTarget::PlayEvent( 2411 Translator* aTranslator) const { 2412 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2413 if (!dt) { 2414 return false; 2415 } 2416 2417 RefPtr<DrawTarget> newDT = dt->CreateClippedDrawTarget(mBounds, mFormat); 2418 2419 // If we couldn't create a DrawTarget this will probably cause us to crash 2420 // with nullptr later in the playback, so return false to abort. 2421 if (!newDT) { 2422 return false; 2423 } 2424 2425 aTranslator->AddDrawTarget(mRefPtr, newDT); 2426 return true; 2427 } 2428 2429 template <class S> 2430 void RecordedCreateClippedDrawTarget::Record(S& aStream) const { 2431 WriteElement(aStream, mRefPtr); 2432 WriteElement(aStream, mBounds); 2433 WriteElement(aStream, mFormat); 2434 } 2435 2436 template <class S> 2437 RecordedCreateClippedDrawTarget::RecordedCreateClippedDrawTarget(S& aStream) 2438 : RecordedEventDerived(CREATECLIPPEDDRAWTARGET) { 2439 ReadElement(aStream, mRefPtr); 2440 ReadElement(aStream, mBounds); 2441 ReadElementConstrained(aStream, mFormat, SurfaceFormat::B8G8R8A8, 2442 SurfaceFormat::UNKNOWN); 2443 } 2444 2445 inline void RecordedCreateClippedDrawTarget::OutputSimpleEventInfo( 2446 std::stringstream& aStringStream) const { 2447 aStringStream << "[" << mRefPtr << "] CreateClippedDrawTarget ()"; 2448 } 2449 2450 template <class S> 2451 void RecordedCreateDrawTargetForFilter::Record(S& aStream) const { 2452 WriteElement(aStream, mRefPtr); 2453 WriteElement(aStream, mMaxSize); 2454 WriteElement(aStream, mFormat); 2455 WriteElement(aStream, mFilter); 2456 WriteElement(aStream, mSource); 2457 WriteElement(aStream, mSourceRect); 2458 WriteElement(aStream, mDestPoint); 2459 } 2460 2461 template <class S> 2462 RecordedCreateDrawTargetForFilter::RecordedCreateDrawTargetForFilter(S& aStream) 2463 : RecordedEventDerived(CREATEDRAWTARGETFORFILTER) { 2464 ReadElement(aStream, mRefPtr); 2465 ReadElement(aStream, mMaxSize); 2466 ReadElementConstrained(aStream, mFormat, SurfaceFormat::B8G8R8A8, 2467 SurfaceFormat::UNKNOWN); 2468 ReadElement(aStream, mFilter); 2469 ReadElement(aStream, mSource); 2470 ReadElement(aStream, mSourceRect); 2471 ReadElement(aStream, mDestPoint); 2472 } 2473 2474 inline void RecordedCreateDrawTargetForFilter::OutputSimpleEventInfo( 2475 std::stringstream& aStringStream) const { 2476 aStringStream << "[" << mRefPtr << "] CreateDrawTargetForFilter ()"; 2477 } 2478 2479 struct GenericPattern { 2480 GenericPattern(const PatternStorage& aStorage, Translator* aTranslator) 2481 : mPattern(nullptr), mTranslator(aTranslator) { 2482 mStorage = const_cast<PatternStorage*>(&aStorage); 2483 } 2484 2485 ~GenericPattern() { 2486 if (mPattern) { 2487 mPattern->~Pattern(); 2488 } 2489 } 2490 2491 operator Pattern*() { 2492 switch (mStorage->mType) { 2493 case PatternType::COLOR: 2494 return new (mColPat) ColorPattern( 2495 reinterpret_cast<ColorPatternStorage*>(&mStorage->mStorage) 2496 ->mColor); 2497 case PatternType::SURFACE: { 2498 SurfacePatternStorage* storage = 2499 reinterpret_cast<SurfacePatternStorage*>(&mStorage->mStorage); 2500 mPattern = new (mSurfPat) 2501 SurfacePattern(mTranslator->LookupSourceSurface(storage->mSurface), 2502 storage->mExtend, storage->mMatrix, 2503 storage->mSamplingFilter, storage->mSamplingRect); 2504 return mPattern; 2505 } 2506 case PatternType::LINEAR_GRADIENT: { 2507 LinearGradientPatternStorage* storage = 2508 reinterpret_cast<LinearGradientPatternStorage*>( 2509 &mStorage->mStorage); 2510 mPattern = new (mLinGradPat) LinearGradientPattern( 2511 storage->mBegin, storage->mEnd, 2512 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops) 2513 : nullptr, 2514 storage->mMatrix); 2515 return mPattern; 2516 } 2517 case PatternType::RADIAL_GRADIENT: { 2518 RadialGradientPatternStorage* storage = 2519 reinterpret_cast<RadialGradientPatternStorage*>( 2520 &mStorage->mStorage); 2521 mPattern = new (mRadGradPat) RadialGradientPattern( 2522 storage->mCenter1, storage->mCenter2, storage->mRadius1, 2523 storage->mRadius2, 2524 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops) 2525 : nullptr, 2526 storage->mMatrix); 2527 return mPattern; 2528 } 2529 case PatternType::CONIC_GRADIENT: { 2530 ConicGradientPatternStorage* storage = 2531 reinterpret_cast<ConicGradientPatternStorage*>(&mStorage->mStorage); 2532 mPattern = new (mConGradPat) ConicGradientPattern( 2533 storage->mCenter, storage->mAngle, storage->mStartOffset, 2534 storage->mEndOffset, 2535 storage->mStops ? mTranslator->LookupGradientStops(storage->mStops) 2536 : nullptr, 2537 storage->mMatrix); 2538 return mPattern; 2539 } 2540 default: 2541 return new (mColPat) ColorPattern(DeviceColor()); 2542 } 2543 2544 return mPattern; 2545 } 2546 2547 union { 2548 char mColPat[sizeof(ColorPattern)]; 2549 char mLinGradPat[sizeof(LinearGradientPattern)]; 2550 char mRadGradPat[sizeof(RadialGradientPattern)]; 2551 char mConGradPat[sizeof(ConicGradientPattern)]; 2552 char mSurfPat[sizeof(SurfacePattern)]; 2553 }; 2554 2555 PatternStorage* mStorage; 2556 Pattern* mPattern; 2557 Translator* mTranslator; 2558 }; 2559 2560 inline bool RecordedFillRect::PlayEvent(Translator* aTranslator) const { 2561 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2562 if (!dt) { 2563 return false; 2564 } 2565 2566 dt->FillRect(mRect, *GenericPattern(mPattern, aTranslator), mOptions); 2567 return true; 2568 } 2569 2570 template <class S> 2571 void RecordedFillRect::Record(S& aStream) const { 2572 WriteElement(aStream, mRect); 2573 WriteElement(aStream, mOptions); 2574 RecordPatternData(aStream, mPattern); 2575 } 2576 2577 template <class S> 2578 RecordedFillRect::RecordedFillRect(S& aStream) 2579 : RecordedEventDerived(FILLRECT) { 2580 ReadElement(aStream, mRect); 2581 ReadDrawOptions(aStream, mOptions); 2582 ReadPatternData(aStream, mPattern); 2583 } 2584 2585 inline void RecordedFillRect::OutputSimpleEventInfo( 2586 std::stringstream& aStringStream) const { 2587 aStringStream << "FillRect (" << mRect.X() << ", " << mRect.Y() << " - " 2588 << mRect.Width() << " x " << mRect.Height() << ") "; 2589 OutputSimplePatternInfo(mPattern, aStringStream); 2590 } 2591 2592 inline bool RecordedStrokeRect::PlayEvent(Translator* aTranslator) const { 2593 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2594 if (!dt) { 2595 return false; 2596 } 2597 2598 dt->StrokeRect(mRect, *GenericPattern(mPattern, aTranslator), mStrokeOptions, 2599 mOptions); 2600 return true; 2601 } 2602 2603 template <class S> 2604 void RecordedStrokeRect::Record(S& aStream) const { 2605 WriteElement(aStream, mRect); 2606 WriteElement(aStream, mOptions); 2607 RecordPatternData(aStream, mPattern); 2608 RecordStrokeOptions(aStream, mStrokeOptions); 2609 } 2610 2611 template <class S> 2612 RecordedStrokeRect::RecordedStrokeRect(S& aStream) 2613 : RecordedEventDerived(STROKERECT) { 2614 ReadElement(aStream, mRect); 2615 ReadDrawOptions(aStream, mOptions); 2616 ReadPatternData(aStream, mPattern); 2617 ReadStrokeOptions(aStream, mStrokeOptions); 2618 } 2619 2620 inline void RecordedStrokeRect::OutputSimpleEventInfo( 2621 std::stringstream& aStringStream) const { 2622 aStringStream << "StrokeRect (" << mRect.X() << ", " << mRect.Y() << " - " 2623 << mRect.Width() << " x " << mRect.Height() 2624 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px "; 2625 OutputSimplePatternInfo(mPattern, aStringStream); 2626 } 2627 2628 inline bool RecordedStrokeLine::PlayEvent(Translator* aTranslator) const { 2629 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2630 if (!dt) { 2631 return false; 2632 } 2633 2634 dt->StrokeLine(mBegin, mEnd, *GenericPattern(mPattern, aTranslator), 2635 mStrokeOptions, mOptions); 2636 return true; 2637 } 2638 2639 template <class S> 2640 void RecordedStrokeLine::Record(S& aStream) const { 2641 WriteElement(aStream, mBegin); 2642 WriteElement(aStream, mEnd); 2643 WriteElement(aStream, mOptions); 2644 RecordPatternData(aStream, mPattern); 2645 RecordStrokeOptions(aStream, mStrokeOptions); 2646 } 2647 2648 template <class S> 2649 RecordedStrokeLine::RecordedStrokeLine(S& aStream) 2650 : RecordedEventDerived(STROKELINE) { 2651 ReadElement(aStream, mBegin); 2652 ReadElement(aStream, mEnd); 2653 ReadDrawOptions(aStream, mOptions); 2654 ReadPatternData(aStream, mPattern); 2655 ReadStrokeOptions(aStream, mStrokeOptions); 2656 } 2657 2658 inline void RecordedStrokeLine::OutputSimpleEventInfo( 2659 std::stringstream& aStringStream) const { 2660 aStringStream << "StrokeLine (" << mBegin.x << ", " << mBegin.y << " - " 2661 << mEnd.x << ", " << mEnd.y 2662 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px "; 2663 OutputSimplePatternInfo(mPattern, aStringStream); 2664 } 2665 2666 inline bool RecordedStrokeCircle::PlayEvent(Translator* aTranslator) const { 2667 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2668 if (!dt) { 2669 return false; 2670 } 2671 2672 dt->StrokeCircle(mCircle.origin, mCircle.radius, 2673 *GenericPattern(mPattern, aTranslator), mStrokeOptions, 2674 mOptions); 2675 return true; 2676 } 2677 2678 template <class S> 2679 void RecordedStrokeCircle::Record(S& aStream) const { 2680 WriteElement(aStream, mCircle); 2681 WriteElement(aStream, mOptions); 2682 RecordPatternData(aStream, mPattern); 2683 RecordStrokeOptions(aStream, mStrokeOptions); 2684 } 2685 2686 template <class S> 2687 RecordedStrokeCircle::RecordedStrokeCircle(S& aStream) 2688 : RecordedEventDerived(STROKECIRCLE) { 2689 ReadElement(aStream, mCircle); 2690 ReadDrawOptions(aStream, mOptions); 2691 ReadPatternData(aStream, mPattern); 2692 ReadStrokeOptions(aStream, mStrokeOptions); 2693 } 2694 2695 inline void RecordedStrokeCircle::OutputSimpleEventInfo( 2696 std::stringstream& aStringStream) const { 2697 aStringStream << "StrokeCircle (" << mCircle.origin.x << ", " 2698 << mCircle.origin.y << " - " << mCircle.radius 2699 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px "; 2700 OutputSimplePatternInfo(mPattern, aStringStream); 2701 } 2702 2703 inline bool RecordedFill::PlayEvent(Translator* aTranslator) const { 2704 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2705 if (!dt) { 2706 return false; 2707 } 2708 2709 dt->Fill(aTranslator->LookupPath(mPath), 2710 *GenericPattern(mPattern, aTranslator), mOptions); 2711 return true; 2712 } 2713 2714 template <class S> 2715 RecordedFill::RecordedFill(S& aStream) : RecordedEventDerived(FILL) { 2716 ReadElement(aStream, mPath); 2717 ReadDrawOptions(aStream, mOptions); 2718 ReadPatternData(aStream, mPattern); 2719 } 2720 2721 template <class S> 2722 void RecordedFill::Record(S& aStream) const { 2723 WriteElement(aStream, mPath); 2724 WriteElement(aStream, mOptions); 2725 RecordPatternData(aStream, mPattern); 2726 } 2727 2728 inline void RecordedFill::OutputSimpleEventInfo( 2729 std::stringstream& aStringStream) const { 2730 aStringStream << "Fill (" << mPath << ") "; 2731 OutputSimplePatternInfo(mPattern, aStringStream); 2732 } 2733 2734 inline bool RecordedFillCircle::PlayEvent(Translator* aTranslator) const { 2735 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2736 if (!dt) { 2737 return false; 2738 } 2739 2740 dt->FillCircle(mCircle.origin, mCircle.radius, 2741 *GenericPattern(mPattern, aTranslator), mOptions); 2742 return true; 2743 } 2744 2745 template <class S> 2746 void RecordedFillCircle::Record(S& aStream) const { 2747 WriteElement(aStream, mCircle); 2748 WriteElement(aStream, mOptions); 2749 RecordPatternData(aStream, mPattern); 2750 } 2751 2752 template <class S> 2753 RecordedFillCircle::RecordedFillCircle(S& aStream) 2754 : RecordedEventDerived(FILLCIRCLE) { 2755 ReadElement(aStream, mCircle); 2756 ReadDrawOptions(aStream, mOptions); 2757 ReadPatternData(aStream, mPattern); 2758 } 2759 2760 inline void RecordedFillCircle::OutputSimpleEventInfo( 2761 std::stringstream& aStringStream) const { 2762 aStringStream << "FillCircle (" << mCircle.origin.x << ", " 2763 << mCircle.origin.y << " - " << mCircle.radius << ")"; 2764 OutputSimplePatternInfo(mPattern, aStringStream); 2765 } 2766 2767 template <class T> 2768 inline bool RecordedDrawGlyphs<T>::PlayEvent(Translator* aTranslator) const { 2769 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2770 if (!dt) { 2771 return false; 2772 } 2773 2774 ScaledFont* scaledFont = aTranslator->LookupScaledFont(mScaledFont); 2775 if (!scaledFont) { 2776 return false; 2777 } 2778 2779 GlyphBuffer buffer; 2780 buffer.mGlyphs = mGlyphs.data(); 2781 buffer.mNumGlyphs = mGlyphs.size(); 2782 DrawGlyphs(dt, scaledFont, buffer, *GenericPattern(mPattern, aTranslator)); 2783 return true; 2784 } 2785 2786 template <class T> 2787 template <class S> 2788 RecordedDrawGlyphs<T>::RecordedDrawGlyphs(RecordedEvent::EventType aType, 2789 S& aStream) 2790 : RecordedEventDerived<T>(aType) { 2791 ReadElement(aStream, mScaledFont); 2792 ReadDrawOptions(aStream, mOptions); 2793 this->ReadPatternData(aStream, mPattern); 2794 uint32_t numGlyphs = 0; 2795 ReadElement(aStream, numGlyphs); 2796 if (!aStream.good() || numGlyphs <= 0) { 2797 return; 2798 } 2799 2800 if (!mGlyphs.Read(aStream, numGlyphs)) { 2801 gfxCriticalNote << "RecordedDrawGlyphs failed to allocate glyphs of size " 2802 << numGlyphs; 2803 aStream.SetIsBad(); 2804 } 2805 } 2806 2807 template <class T> 2808 template <class S> 2809 void RecordedDrawGlyphs<T>::Record(S& aStream) const { 2810 WriteElement(aStream, mScaledFont); 2811 WriteElement(aStream, mOptions); 2812 this->RecordPatternData(aStream, mPattern); 2813 WriteElement(aStream, mGlyphs.size()); 2814 mGlyphs.Write(aStream); 2815 } 2816 2817 template <class T> 2818 inline void RecordedDrawGlyphs<T>::OutputSimpleEventInfo( 2819 std::stringstream& aStringStream) const { 2820 aStringStream << this->GetName() << " (" << mScaledFont << ") "; 2821 this->OutputSimplePatternInfo(mPattern, aStringStream); 2822 } 2823 2824 inline bool RecordedMask::PlayEvent(Translator* aTranslator) const { 2825 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2826 if (!dt) { 2827 return false; 2828 } 2829 2830 dt->Mask(*GenericPattern(mSource, aTranslator), 2831 *GenericPattern(mMask, aTranslator), mOptions); 2832 return true; 2833 } 2834 2835 template <class S> 2836 RecordedMask::RecordedMask(S& aStream) : RecordedEventDerived(MASK) { 2837 ReadDrawOptions(aStream, mOptions); 2838 ReadPatternData(aStream, mSource); 2839 ReadPatternData(aStream, mMask); 2840 } 2841 2842 template <class S> 2843 void RecordedMask::Record(S& aStream) const { 2844 WriteElement(aStream, mOptions); 2845 RecordPatternData(aStream, mSource); 2846 RecordPatternData(aStream, mMask); 2847 } 2848 2849 inline void RecordedMask::OutputSimpleEventInfo( 2850 std::stringstream& aStringStream) const { 2851 aStringStream << "Mask (Source: "; 2852 OutputSimplePatternInfo(mSource, aStringStream); 2853 aStringStream << " Mask: "; 2854 OutputSimplePatternInfo(mMask, aStringStream); 2855 } 2856 2857 inline bool RecordedStroke::PlayEvent(Translator* aTranslator) const { 2858 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2859 if (!dt) { 2860 return false; 2861 } 2862 2863 Path* path = aTranslator->LookupPath(mPath); 2864 if (!path) { 2865 return false; 2866 } 2867 2868 dt->Stroke(path, *GenericPattern(mPattern, aTranslator), mStrokeOptions, 2869 mOptions); 2870 return true; 2871 } 2872 2873 template <class S> 2874 void RecordedStroke::Record(S& aStream) const { 2875 WriteElement(aStream, mPath); 2876 WriteElement(aStream, mOptions); 2877 RecordPatternData(aStream, mPattern); 2878 RecordStrokeOptions(aStream, mStrokeOptions); 2879 } 2880 2881 template <class S> 2882 RecordedStroke::RecordedStroke(S& aStream) : RecordedEventDerived(STROKE) { 2883 ReadElement(aStream, mPath); 2884 ReadDrawOptions(aStream, mOptions); 2885 ReadPatternData(aStream, mPattern); 2886 ReadStrokeOptions(aStream, mStrokeOptions); 2887 } 2888 2889 inline void RecordedStroke::OutputSimpleEventInfo( 2890 std::stringstream& aStringStream) const { 2891 aStringStream << "Stroke (" << mPath 2892 << ") LineWidth: " << mStrokeOptions.mLineWidth << "px "; 2893 OutputSimplePatternInfo(mPattern, aStringStream); 2894 } 2895 2896 inline bool RecordedClearRect::PlayEvent(Translator* aTranslator) const { 2897 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2898 if (!dt) { 2899 return false; 2900 } 2901 2902 dt->ClearRect(mRect); 2903 return true; 2904 } 2905 2906 template <class S> 2907 void RecordedClearRect::Record(S& aStream) const { 2908 WriteElement(aStream, mRect); 2909 } 2910 2911 template <class S> 2912 RecordedClearRect::RecordedClearRect(S& aStream) 2913 : RecordedEventDerived(CLEARRECT) { 2914 ReadElement(aStream, mRect); 2915 } 2916 2917 inline void RecordedClearRect::OutputSimpleEventInfo( 2918 std::stringstream& aStringStream) const { 2919 aStringStream << "ClearRect (" << mRect.X() << ", " << mRect.Y() << " - " 2920 << mRect.Width() << " x " << mRect.Height() << ") "; 2921 } 2922 2923 inline bool RecordedCopySurface::PlayEvent(Translator* aTranslator) const { 2924 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2925 if (!dt) { 2926 return false; 2927 } 2928 2929 SourceSurface* surface = aTranslator->LookupSourceSurface(mSourceSurface); 2930 if (!surface) { 2931 return false; 2932 } 2933 2934 dt->CopySurface(surface, mSourceRect, mDest); 2935 return true; 2936 } 2937 2938 template <class S> 2939 void RecordedCopySurface::Record(S& aStream) const { 2940 WriteElement(aStream, mSourceSurface); 2941 WriteElement(aStream, mSourceRect); 2942 WriteElement(aStream, mDest); 2943 } 2944 2945 template <class S> 2946 RecordedCopySurface::RecordedCopySurface(S& aStream) 2947 : RecordedEventDerived(COPYSURFACE) { 2948 ReadElement(aStream, mSourceSurface); 2949 ReadElement(aStream, mSourceRect); 2950 ReadElement(aStream, mDest); 2951 } 2952 2953 inline void RecordedCopySurface::OutputSimpleEventInfo( 2954 std::stringstream& aStringStream) const { 2955 aStringStream << "CopySurface (" << mSourceSurface << ")"; 2956 } 2957 2958 inline bool RecordedPushClip::PlayEvent(Translator* aTranslator) const { 2959 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2960 if (!dt) { 2961 return false; 2962 } 2963 2964 Path* path = aTranslator->LookupPath(mPath); 2965 if (!path) { 2966 return false; 2967 } 2968 2969 dt->PushClip(path); 2970 return true; 2971 } 2972 2973 template <class S> 2974 void RecordedPushClip::Record(S& aStream) const { 2975 WriteElement(aStream, mPath); 2976 } 2977 2978 template <class S> 2979 RecordedPushClip::RecordedPushClip(S& aStream) 2980 : RecordedEventDerived(PUSHCLIP) { 2981 ReadElement(aStream, mPath); 2982 } 2983 2984 inline void RecordedPushClip::OutputSimpleEventInfo( 2985 std::stringstream& aStringStream) const { 2986 aStringStream << "PushClip (" << mPath << ") "; 2987 } 2988 2989 inline bool RecordedPushClipRect::PlayEvent(Translator* aTranslator) const { 2990 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 2991 if (!dt) { 2992 return false; 2993 } 2994 2995 dt->PushClipRect(mRect); 2996 return true; 2997 } 2998 2999 template <class S> 3000 void RecordedPushClipRect::Record(S& aStream) const { 3001 WriteElement(aStream, mRect); 3002 } 3003 3004 template <class S> 3005 RecordedPushClipRect::RecordedPushClipRect(S& aStream) 3006 : RecordedEventDerived(PUSHCLIPRECT) { 3007 ReadElement(aStream, mRect); 3008 } 3009 3010 inline void RecordedPushClipRect::OutputSimpleEventInfo( 3011 std::stringstream& aStringStream) const { 3012 aStringStream << "PushClipRect (" << mRect.X() << ", " << mRect.Y() << " - " 3013 << mRect.Width() << " x " << mRect.Height() << ") "; 3014 } 3015 3016 inline bool RecordedPopClip::PlayEvent(Translator* aTranslator) const { 3017 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3018 if (!dt) { 3019 return false; 3020 } 3021 3022 dt->PopClip(); 3023 return true; 3024 } 3025 3026 template <class S> 3027 void RecordedPopClip::Record(S& aStream) const {} 3028 3029 template <class S> 3030 RecordedPopClip::RecordedPopClip(S& aStream) : RecordedEventDerived(POPCLIP) {} 3031 3032 inline void RecordedPopClip::OutputSimpleEventInfo( 3033 std::stringstream& aStringStream) const { 3034 aStringStream << "PopClip"; 3035 } 3036 3037 inline bool RecordedRemoveAllClips::PlayEvent(Translator* aTranslator) const { 3038 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3039 if (!dt) { 3040 return false; 3041 } 3042 3043 dt->RemoveAllClips(); 3044 return true; 3045 } 3046 3047 template <class S> 3048 void RecordedRemoveAllClips::Record(S& aStream) const {} 3049 3050 template <class S> 3051 RecordedRemoveAllClips::RecordedRemoveAllClips(S& aStream) 3052 : RecordedEventDerived(REMOVEALLCLIPS) {} 3053 3054 inline void RecordedRemoveAllClips::OutputSimpleEventInfo( 3055 std::stringstream& aStringStream) const { 3056 aStringStream << "RemoveAllClips"; 3057 } 3058 3059 inline bool RecordedPushLayer::PlayEvent(Translator* aTranslator) const { 3060 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3061 if (!dt) { 3062 return false; 3063 } 3064 3065 SourceSurface* mask = 3066 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr; 3067 dt->PushLayer(mOpaque, mOpacity, mask, mMaskTransform, mBounds, 3068 mCopyBackground); 3069 return true; 3070 } 3071 3072 template <class S> 3073 void RecordedPushLayer::Record(S& aStream) const { 3074 WriteElement(aStream, mOpaque); 3075 WriteElement(aStream, mOpacity); 3076 WriteElement(aStream, mMask); 3077 WriteElement(aStream, mMaskTransform); 3078 WriteElement(aStream, mBounds); 3079 WriteElement(aStream, mCopyBackground); 3080 } 3081 3082 template <class S> 3083 RecordedPushLayer::RecordedPushLayer(S& aStream) 3084 : RecordedEventDerived(PUSHLAYER) { 3085 ReadElement(aStream, mOpaque); 3086 ReadElement(aStream, mOpacity); 3087 ReadElement(aStream, mMask); 3088 ReadElement(aStream, mMaskTransform); 3089 ReadElement(aStream, mBounds); 3090 ReadElement(aStream, mCopyBackground); 3091 } 3092 3093 inline void RecordedPushLayer::OutputSimpleEventInfo( 3094 std::stringstream& aStringStream) const { 3095 aStringStream << "PushPLayer (Opaque=" << mOpaque << ", Opacity=" << mOpacity 3096 << ", Mask Ref=" << mMask << ") "; 3097 } 3098 3099 inline bool RecordedPushLayerWithBlend::PlayEvent( 3100 Translator* aTranslator) const { 3101 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3102 if (!dt) { 3103 return false; 3104 } 3105 3106 SourceSurface* mask = 3107 mMask ? aTranslator->LookupSourceSurface(mMask) : nullptr; 3108 dt->PushLayerWithBlend(mOpaque, mOpacity, mask, mMaskTransform, mBounds, 3109 mCopyBackground, mCompositionOp); 3110 return true; 3111 } 3112 3113 template <class S> 3114 void RecordedPushLayerWithBlend::Record(S& aStream) const { 3115 WriteElement(aStream, mOpaque); 3116 WriteElement(aStream, mOpacity); 3117 WriteElement(aStream, mMask); 3118 WriteElement(aStream, mMaskTransform); 3119 WriteElement(aStream, mBounds); 3120 WriteElement(aStream, mCopyBackground); 3121 WriteElement(aStream, mCompositionOp); 3122 } 3123 3124 template <class S> 3125 RecordedPushLayerWithBlend::RecordedPushLayerWithBlend(S& aStream) 3126 : RecordedEventDerived(PUSHLAYERWITHBLEND) { 3127 ReadElement(aStream, mOpaque); 3128 ReadElement(aStream, mOpacity); 3129 ReadElement(aStream, mMask); 3130 ReadElement(aStream, mMaskTransform); 3131 ReadElement(aStream, mBounds); 3132 ReadElement(aStream, mCopyBackground); 3133 ReadElementConstrained(aStream, mCompositionOp, CompositionOp::OP_OVER, 3134 CompositionOp::OP_COUNT); 3135 } 3136 3137 inline void RecordedPushLayerWithBlend::OutputSimpleEventInfo( 3138 std::stringstream& aStringStream) const { 3139 aStringStream << "PushLayerWithBlend (Opaque=" << mOpaque 3140 << ", Opacity=" << mOpacity << ", Mask Ref=" << mMask << ") "; 3141 } 3142 3143 inline bool RecordedPopLayer::PlayEvent(Translator* aTranslator) const { 3144 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3145 if (!dt) { 3146 return false; 3147 } 3148 3149 dt->PopLayer(); 3150 return true; 3151 } 3152 3153 template <class S> 3154 void RecordedPopLayer::Record(S& aStream) const {} 3155 3156 template <class S> 3157 RecordedPopLayer::RecordedPopLayer(S& aStream) 3158 : RecordedEventDerived(POPLAYER) {} 3159 3160 inline void RecordedPopLayer::OutputSimpleEventInfo( 3161 std::stringstream& aStringStream) const { 3162 aStringStream << "PopLayer"; 3163 } 3164 3165 inline bool RecordedSetPermitSubpixelAA::PlayEvent( 3166 Translator* aTranslator) const { 3167 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3168 if (!dt) { 3169 return false; 3170 } 3171 3172 dt->SetPermitSubpixelAA(mPermitSubpixelAA); 3173 return true; 3174 } 3175 3176 template <class S> 3177 void RecordedSetPermitSubpixelAA::Record(S& aStream) const { 3178 WriteElement(aStream, mPermitSubpixelAA); 3179 } 3180 3181 template <class S> 3182 RecordedSetPermitSubpixelAA::RecordedSetPermitSubpixelAA(S& aStream) 3183 : RecordedEventDerived(SETPERMITSUBPIXELAA) { 3184 ReadElement(aStream, mPermitSubpixelAA); 3185 } 3186 3187 inline void RecordedSetPermitSubpixelAA::OutputSimpleEventInfo( 3188 std::stringstream& aStringStream) const { 3189 aStringStream << "SetPermitSubpixelAA (" << mPermitSubpixelAA << ")"; 3190 } 3191 3192 inline bool RecordedSetTransform::PlayEvent(Translator* aTranslator) const { 3193 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3194 if (!dt) { 3195 return false; 3196 } 3197 3198 // If we're drawing to the reference DT, then we need to manually apply 3199 // its initial transform, otherwise we'll just clobber it with only the 3200 // the transform that was visible to the code doing the recording. 3201 if (dt == aTranslator->GetReferenceDrawTarget()) { 3202 dt->SetTransform(mTransform * 3203 aTranslator->GetReferenceDrawTargetTransform()); 3204 } else { 3205 dt->SetTransform(mTransform); 3206 } 3207 3208 return true; 3209 } 3210 3211 template <class S> 3212 void RecordedSetTransform::Record(S& aStream) const { 3213 WriteElement(aStream, mTransform); 3214 } 3215 3216 template <class S> 3217 RecordedSetTransform::RecordedSetTransform(S& aStream) 3218 : RecordedEventDerived(SETTRANSFORM) { 3219 ReadElement(aStream, mTransform); 3220 } 3221 3222 inline void RecordedSetTransform::OutputSimpleEventInfo( 3223 std::stringstream& aStringStream) const { 3224 aStringStream << "SetTransform [ " << mTransform._11 << " " << mTransform._12 3225 << " ; " << mTransform._21 << " " << mTransform._22 << " ; " 3226 << mTransform._31 << " " << mTransform._32 << " ]"; 3227 } 3228 3229 inline bool RecordedDrawSurface::PlayEvent(Translator* aTranslator) const { 3230 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3231 if (!dt) { 3232 return false; 3233 } 3234 3235 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource); 3236 if (!surface) { 3237 return false; 3238 } 3239 3240 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions); 3241 return true; 3242 } 3243 3244 template <class S> 3245 void RecordedDrawSurface::Record(S& aStream) const { 3246 WriteElement(aStream, mRefSource); 3247 WriteElement(aStream, mDest); 3248 WriteElement(aStream, mSource); 3249 WriteElement(aStream, mDSOptions); 3250 WriteElement(aStream, mOptions); 3251 } 3252 3253 template <class S> 3254 RecordedDrawSurface::RecordedDrawSurface(S& aStream) 3255 : RecordedEventDerived(DRAWSURFACE) { 3256 ReadElement(aStream, mRefSource); 3257 ReadElement(aStream, mDest); 3258 ReadElement(aStream, mSource); 3259 ReadDrawSurfaceOptions(aStream, mDSOptions); 3260 ReadDrawOptions(aStream, mOptions); 3261 } 3262 3263 inline void RecordedDrawSurface::OutputSimpleEventInfo( 3264 std::stringstream& aStringStream) const { 3265 aStringStream << "DrawSurface (" << mRefSource << ")"; 3266 } 3267 3268 inline bool RecordedDrawSurfaceDescriptor::PlayEvent( 3269 Translator* aTranslator) const { 3270 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3271 if (!dt) { 3272 return false; 3273 } 3274 3275 RefPtr<SourceSurface> surface = 3276 aTranslator->LookupSourceSurfaceFromSurfaceDescriptor(mDesc); 3277 if (!surface) { 3278 return false; 3279 } 3280 3281 RefPtr<SourceSurface> opt = dt->OptimizeSourceSurface(surface); 3282 if (opt) { 3283 surface = opt; 3284 } 3285 3286 dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions); 3287 return true; 3288 } 3289 3290 template <class S> 3291 struct ElementStreamFormat<S, layers::SurfaceDescriptor> { 3292 using T = layers::SurfaceDescriptor; 3293 3294 static void Write(S& s, const T& t) { 3295 Maybe<T> valid; 3296 if (!dom::ValidSurfaceDescriptorForRemoteCanvas2d(t, &valid)) { 3297 MOZ_CRASH("Invalid surface descriptor for write"); 3298 } 3299 MOZ_RELEASE_ASSERT(valid && *valid == t); 3300 3301 nsTArray<char> buffer; 3302 mozilla::ipc::SerializeToBytesUtil(*valid, buffer); 3303 3304 uint32_t size = buffer.Length(); 3305 s.write(reinterpret_cast<const char*>(&size), sizeof(size)); 3306 if (size > 0) { 3307 s.write(buffer.Elements(), size); 3308 } 3309 } 3310 3311 static void Read(S& s, T& t) { 3312 uint32_t size = 0; 3313 s.read(reinterpret_cast<char*>(&size), sizeof(size)); 3314 3315 if (!s.good() || size == 0 || size > 1024 * 16) { 3316 s.SetIsBad(); 3317 return; 3318 } 3319 3320 // TODO: We should revise/extend the API to avoid copying here. 3321 nsTArray<char> buffer; 3322 buffer.SetLength(size); 3323 s.read(buffer.Elements(), size); 3324 3325 if (!s.good()) { 3326 return; 3327 } 3328 3329 auto result = mozilla::ipc::DeserializeFromBytesUtil<T>(buffer); 3330 if (!result) { 3331 s.SetIsBad(); 3332 return; 3333 } 3334 3335 t = std::move(*result); 3336 3337 if (!dom::ValidSurfaceDescriptorForRemoteCanvas2d(t)) { 3338 s.SetIsBad(); 3339 return; 3340 } 3341 } 3342 }; 3343 3344 template <class S> 3345 void RecordedDrawSurfaceDescriptor::Record(S& aStream) const { 3346 WriteElement(aStream, mDesc); 3347 WriteElement(aStream, mDest); 3348 WriteElement(aStream, mSource); 3349 WriteElement(aStream, mDSOptions); 3350 WriteElement(aStream, mOptions); 3351 } 3352 3353 template <class S> 3354 RecordedDrawSurfaceDescriptor::RecordedDrawSurfaceDescriptor(S& aStream) 3355 : RecordedEventDerived(DRAWSURFACEDESCRIPTOR) { 3356 ReadElement(aStream, mDesc); 3357 ReadElement(aStream, mDest); 3358 ReadElement(aStream, mSource); 3359 ReadDrawSurfaceOptions(aStream, mDSOptions); 3360 ReadDrawOptions(aStream, mOptions); 3361 } 3362 3363 inline void RecordedDrawSurfaceDescriptor::OutputSimpleEventInfo( 3364 std::stringstream& aStringStream) const { 3365 aStringStream << "DrawSurfaceDescriptor (" << mDesc.type() << ")"; 3366 } 3367 3368 inline bool RecordedDrawDependentSurface::PlayEvent( 3369 Translator* aTranslator) const { 3370 aTranslator->DrawDependentSurface(mId, mDest); 3371 return true; 3372 } 3373 3374 template <class S> 3375 void RecordedDrawDependentSurface::Record(S& aStream) const { 3376 WriteElement(aStream, mId); 3377 WriteElement(aStream, mDest); 3378 } 3379 3380 template <class S> 3381 RecordedDrawDependentSurface::RecordedDrawDependentSurface(S& aStream) 3382 : RecordedEventDerived(DRAWDEPENDENTSURFACE) { 3383 ReadElement(aStream, mId); 3384 ReadElement(aStream, mDest); 3385 } 3386 3387 inline void RecordedDrawDependentSurface::OutputSimpleEventInfo( 3388 std::stringstream& aStringStream) const { 3389 aStringStream << "DrawDependentSurface (" << mId << ")"; 3390 } 3391 3392 inline bool RecordedDrawFilter::PlayEvent(Translator* aTranslator) const { 3393 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3394 if (!dt) { 3395 return false; 3396 } 3397 3398 FilterNode* filter = aTranslator->LookupFilterNode(mNode); 3399 if (!filter) { 3400 return false; 3401 } 3402 3403 dt->DrawFilter(filter, mSourceRect, mDestPoint, mOptions); 3404 return true; 3405 } 3406 3407 template <class S> 3408 void RecordedDrawFilter::Record(S& aStream) const { 3409 WriteElement(aStream, mNode); 3410 WriteElement(aStream, mSourceRect); 3411 WriteElement(aStream, mDestPoint); 3412 WriteElement(aStream, mOptions); 3413 } 3414 3415 template <class S> 3416 RecordedDrawFilter::RecordedDrawFilter(S& aStream) 3417 : RecordedEventDerived(DRAWFILTER) { 3418 ReadElement(aStream, mNode); 3419 ReadElement(aStream, mSourceRect); 3420 ReadElement(aStream, mDestPoint); 3421 ReadDrawOptions(aStream, mOptions); 3422 } 3423 3424 inline void RecordedDrawFilter::OutputSimpleEventInfo( 3425 std::stringstream& aStringStream) const { 3426 aStringStream << "DrawFilter (" << mNode << ")"; 3427 } 3428 3429 inline bool RecordedDrawSurfaceWithShadow::PlayEvent( 3430 Translator* aTranslator) const { 3431 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3432 if (!dt) { 3433 return false; 3434 } 3435 3436 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefSource); 3437 if (!surface) { 3438 return false; 3439 } 3440 3441 dt->DrawSurfaceWithShadow(surface, mDest, mShadow, mOp); 3442 return true; 3443 } 3444 3445 template <class S> 3446 void RecordedDrawSurfaceWithShadow::Record(S& aStream) const { 3447 WriteElement(aStream, mRefSource); 3448 WriteElement(aStream, mDest); 3449 WriteElement(aStream, mShadow); 3450 WriteElement(aStream, mOp); 3451 } 3452 3453 template <class S> 3454 RecordedDrawSurfaceWithShadow::RecordedDrawSurfaceWithShadow(S& aStream) 3455 : RecordedEventDerived(DRAWSURFACEWITHSHADOW) { 3456 ReadElement(aStream, mRefSource); 3457 ReadElement(aStream, mDest); 3458 ReadElement(aStream, mShadow); 3459 ReadElementConstrained(aStream, mOp, CompositionOp::OP_OVER, 3460 CompositionOp::OP_COUNT); 3461 } 3462 3463 inline void RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo( 3464 std::stringstream& aStringStream) const { 3465 aStringStream << "DrawSurfaceWithShadow (" << mRefSource << ") DeviceColor: (" 3466 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", " 3467 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")"; 3468 } 3469 3470 inline bool RecordedDrawShadow::PlayEvent(Translator* aTranslator) const { 3471 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3472 if (!dt) { 3473 return false; 3474 } 3475 3476 Path* path = aTranslator->LookupPath(mPath); 3477 if (!path) { 3478 return false; 3479 } 3480 3481 dt->DrawShadow(path, *GenericPattern(mPattern, aTranslator), mShadow, 3482 mOptions, mHasStrokeOptions ? &mStrokeOptions : nullptr); 3483 return true; 3484 } 3485 3486 template <class S> 3487 void RecordedDrawShadow::Record(S& aStream) const { 3488 WriteElement(aStream, mPath); 3489 RecordPatternData(aStream, mPattern); 3490 WriteElement(aStream, mShadow); 3491 WriteElement(aStream, mOptions); 3492 WriteElement(aStream, mHasStrokeOptions); 3493 if (mHasStrokeOptions) { 3494 RecordStrokeOptions(aStream, mStrokeOptions); 3495 } 3496 } 3497 3498 template <class S> 3499 RecordedDrawShadow::RecordedDrawShadow(S& aStream) 3500 : RecordedEventDerived(DRAWSHADOW) { 3501 ReadElement(aStream, mPath); 3502 ReadPatternData(aStream, mPattern); 3503 ReadElement(aStream, mShadow); 3504 ReadDrawOptions(aStream, mOptions); 3505 ReadElement(aStream, mHasStrokeOptions); 3506 if (mHasStrokeOptions) { 3507 ReadStrokeOptions(aStream, mStrokeOptions); 3508 } 3509 } 3510 3511 inline void RecordedDrawShadow::OutputSimpleEventInfo( 3512 std::stringstream& aStringStream) const { 3513 aStringStream << "DrawShadow (" << mPath << ") DeviceColor: (" 3514 << mShadow.mColor.r << ", " << mShadow.mColor.g << ", " 3515 << mShadow.mColor.b << ", " << mShadow.mColor.a << ")"; 3516 } 3517 3518 inline RecordedPathCreation::RecordedPathCreation(PathRecording* aPath) 3519 : RecordedEventDerived(PATHCREATION), 3520 mRefPtr(aPath), 3521 mFillRule(aPath->mFillRule), 3522 mPath(aPath) {} 3523 3524 inline bool RecordedPathCreation::PlayEvent(Translator* aTranslator) const { 3525 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget(); 3526 if (!drawTarget) { 3527 return false; 3528 } 3529 3530 RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder(mFillRule); 3531 if (!mPathOps->CheckedStreamToSink(*builder)) { 3532 return false; 3533 } 3534 3535 RefPtr<Path> path = builder->Finish(); 3536 aTranslator->AddPath(mRefPtr, path); 3537 return true; 3538 } 3539 3540 template <class S> 3541 void RecordedPathCreation::Record(S& aStream) const { 3542 WriteElement(aStream, mRefPtr); 3543 WriteElement(aStream, mFillRule); 3544 mPath->mPathOps.Record(aStream); 3545 } 3546 3547 template <class S> 3548 RecordedPathCreation::RecordedPathCreation(S& aStream) 3549 : RecordedEventDerived(PATHCREATION) { 3550 ReadElement(aStream, mRefPtr); 3551 ReadElementConstrained(aStream, mFillRule, FillRule::FILL_WINDING, 3552 FillRule::FILL_EVEN_ODD); 3553 mPathOps = MakeUnique<PathOps>(aStream); 3554 } 3555 3556 inline void RecordedPathCreation::OutputSimpleEventInfo( 3557 std::stringstream& aStringStream) const { 3558 size_t numberOfOps = 3559 mPath ? mPath->mPathOps.NumberOfOps() : mPathOps->NumberOfOps(); 3560 aStringStream << "[" << mRefPtr << "] Path created (OpCount: " << numberOfOps 3561 << ")"; 3562 } 3563 inline bool RecordedPathDestruction::PlayEvent(Translator* aTranslator) const { 3564 aTranslator->RemovePath(mRefPtr); 3565 return true; 3566 } 3567 3568 template <class S> 3569 void RecordedPathDestruction::Record(S& aStream) const { 3570 WriteElement(aStream, mRefPtr); 3571 } 3572 3573 template <class S> 3574 RecordedPathDestruction::RecordedPathDestruction(S& aStream) 3575 : RecordedEventDerived(PATHDESTRUCTION) { 3576 ReadElement(aStream, mRefPtr); 3577 } 3578 3579 inline void RecordedPathDestruction::OutputSimpleEventInfo( 3580 std::stringstream& aStringStream) const { 3581 aStringStream << "[" << mRefPtr << "] Path Destroyed"; 3582 } 3583 3584 inline bool RecordedSourceSurfaceCreation::PlayEvent( 3585 Translator* aTranslator) const { 3586 if (!mDataSurface) { 3587 return false; 3588 } 3589 3590 aTranslator->AddSourceSurface(mRefPtr, mDataSurface); 3591 return true; 3592 } 3593 3594 template <class S> 3595 void RecordedSourceSurfaceCreation::Record(S& aStream) const { 3596 MOZ_ASSERT(mDataSurface); 3597 IntSize size = mDataSurface->GetSize(); 3598 SurfaceFormat format = mDataSurface->GetFormat(); 3599 WriteElement(aStream, mRefPtr); 3600 DataSourceSurface::ScopedMap map(mDataSurface, DataSourceSurface::READ); 3601 if (map.IsMapped()) { 3602 WriteElement(aStream, size); 3603 WriteElement(aStream, format); 3604 3605 size_t dataFormatWidth = BytesPerPixel(format) * size.width; 3606 size_t stride = map.GetStride(); 3607 const char* src = (const char*)map.GetData(); 3608 const char* endSrc = src + stride * size.height; 3609 while (src < endSrc) { 3610 aStream.write(src, dataFormatWidth); 3611 src += stride; 3612 } 3613 } else { 3614 gfxWarning() 3615 << "RecordedSourceSurfaceCreation::Record failed to map surface"; 3616 WriteElement(aStream, IntSize(1, 1)); 3617 int bpp = BytesPerPixel(format); 3618 WriteElement(aStream, bpp <= 4 ? format : SurfaceFormat::B8G8R8A8); 3619 static const char zeroData[4] = {0, 0, 0, 0}; 3620 aStream.write(zeroData, BytesPerPixel(format)); 3621 } 3622 } 3623 3624 template <class S> 3625 RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(S& aStream) 3626 : RecordedEventDerived(SOURCESURFACECREATION) { 3627 ReadElement(aStream, mRefPtr); 3628 IntSize size; 3629 ReadElement(aStream, size); 3630 SurfaceFormat format = SurfaceFormat::UNKNOWN; 3631 ReadElementConstrained(aStream, format, SurfaceFormat::B8G8R8A8, 3632 SurfaceFormat::UNKNOWN); 3633 3634 if (!Factory::AllowedSurfaceSize(size)) { 3635 gfxCriticalNote << "RecordedSourceSurfaceCreation read invalid size " 3636 << size; 3637 aStream.SetIsBad(); 3638 } 3639 3640 if (!aStream.good()) { 3641 return; 3642 } 3643 3644 mDataSurface = Factory::CreateDataSourceSurface(size, format); 3645 if (mDataSurface) { 3646 DataSourceSurface::ScopedMap map(mDataSurface, DataSourceSurface::WRITE); 3647 if (!map.IsMapped()) { 3648 mDataSurface = nullptr; 3649 } else { 3650 char* data = (char*)map.GetData(); 3651 size_t stride = map.GetStride(); 3652 size_t dataFormatWidth = BytesPerPixel(format) * size.width; 3653 if (stride == dataFormatWidth) { 3654 aStream.read(data, stride * size.height); 3655 } else { 3656 for (int y = 0; y < size.height; y++) { 3657 aStream.read(data, dataFormatWidth); 3658 data += stride; 3659 } 3660 } 3661 } 3662 } 3663 if (!mDataSurface) { 3664 gfxCriticalNote 3665 << "RecordedSourceSurfaceCreation failed to allocate data of size " 3666 << size.width << " x " << size.height; 3667 aStream.SetIsBad(); 3668 } 3669 } 3670 3671 inline void RecordedSourceSurfaceCreation::OutputSimpleEventInfo( 3672 std::stringstream& aStringStream) const { 3673 if (mDataSurface) { 3674 IntSize size = mDataSurface->GetSize(); 3675 aStringStream << "[" << mRefPtr 3676 << "] SourceSurface created (Size: " << size.width << "x" 3677 << size.height << ")"; 3678 } else { 3679 aStringStream << "[" << mRefPtr << "] SourceSurface created (no data)"; 3680 } 3681 } 3682 3683 inline bool RecordedSourceSurfaceDestruction::PlayEvent( 3684 Translator* aTranslator) const { 3685 aTranslator->RemoveSourceSurface(mRefPtr); 3686 return true; 3687 } 3688 3689 template <class S> 3690 void RecordedSourceSurfaceDestruction::Record(S& aStream) const { 3691 WriteElement(aStream, mRefPtr); 3692 } 3693 3694 template <class S> 3695 RecordedSourceSurfaceDestruction::RecordedSourceSurfaceDestruction(S& aStream) 3696 : RecordedEventDerived(SOURCESURFACEDESTRUCTION) { 3697 ReadElement(aStream, mRefPtr); 3698 } 3699 3700 inline void RecordedSourceSurfaceDestruction::OutputSimpleEventInfo( 3701 std::stringstream& aStringStream) const { 3702 aStringStream << "[" << mRefPtr << "] SourceSurface Destroyed"; 3703 } 3704 3705 inline bool RecordedOptimizeSourceSurface::PlayEvent( 3706 Translator* aTranslator) const { 3707 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3708 if (!dt) { 3709 return false; 3710 } 3711 3712 SourceSurface* surface = aTranslator->LookupSourceSurface(mSurface); 3713 if (!surface) { 3714 return false; 3715 } 3716 3717 RefPtr<SourceSurface> optimizedSurface = dt->OptimizeSourceSurface(surface); 3718 aTranslator->AddSourceSurface(mOptimizedSurface, optimizedSurface); 3719 return true; 3720 } 3721 3722 template <class S> 3723 void RecordedOptimizeSourceSurface::Record(S& aStream) const { 3724 WriteElement(aStream, mSurface); 3725 WriteElement(aStream, mOptimizedSurface); 3726 } 3727 3728 template <class S> 3729 RecordedOptimizeSourceSurface::RecordedOptimizeSourceSurface(S& aStream) 3730 : RecordedEventDerived(OPTIMIZESOURCESURFACE) { 3731 ReadElement(aStream, mSurface); 3732 ReadElement(aStream, mOptimizedSurface); 3733 } 3734 3735 inline void RecordedOptimizeSourceSurface::OutputSimpleEventInfo( 3736 std::stringstream& aStringStream) const { 3737 aStringStream << "[" << mSurface << "] Surface Optimized"; 3738 } 3739 3740 inline bool RecordedExternalSurfaceCreation::PlayEvent( 3741 Translator* aTranslator) const { 3742 RefPtr<SourceSurface> surface = aTranslator->LookupExternalSurface(mKey); 3743 if (!surface) { 3744 return false; 3745 } 3746 3747 aTranslator->AddSourceSurface(mRefPtr, surface); 3748 return true; 3749 } 3750 3751 template <class S> 3752 void RecordedExternalSurfaceCreation::Record(S& aStream) const { 3753 WriteElement(aStream, mRefPtr); 3754 WriteElement(aStream, mKey); 3755 } 3756 3757 template <class S> 3758 RecordedExternalSurfaceCreation::RecordedExternalSurfaceCreation(S& aStream) 3759 : RecordedEventDerived(EXTERNALSURFACECREATION) { 3760 ReadElement(aStream, mRefPtr); 3761 ReadElement(aStream, mKey); 3762 } 3763 3764 inline void RecordedExternalSurfaceCreation::OutputSimpleEventInfo( 3765 std::stringstream& aStringStream) const { 3766 aStringStream << "[" << mRefPtr 3767 << "] SourceSurfaceSharedData created (Key: " << mKey << ")"; 3768 } 3769 3770 inline RecordedFilterNodeCreation::~RecordedFilterNodeCreation() = default; 3771 3772 inline bool RecordedFilterNodeCreation::PlayEvent( 3773 Translator* aTranslator) const { 3774 DrawTarget* drawTarget = aTranslator->GetCurrentDrawTarget(); 3775 if (!drawTarget) { 3776 return false; 3777 } 3778 3779 RefPtr<FilterNode> node = drawTarget->CreateFilter(mType); 3780 aTranslator->AddFilterNode(mRefPtr, node); 3781 return true; 3782 } 3783 3784 template <class S> 3785 void RecordedFilterNodeCreation::Record(S& aStream) const { 3786 WriteElement(aStream, mRefPtr); 3787 WriteElement(aStream, mType); 3788 } 3789 3790 template <class S> 3791 RecordedFilterNodeCreation::RecordedFilterNodeCreation(S& aStream) 3792 : RecordedEventDerived(FILTERNODECREATION) { 3793 ReadElement(aStream, mRefPtr); 3794 ReadElementConstrained(aStream, mType, FilterType::BLEND, 3795 FilterType::OPACITY); 3796 } 3797 3798 inline void RecordedFilterNodeCreation::OutputSimpleEventInfo( 3799 std::stringstream& aStringStream) const { 3800 aStringStream << "CreateFilter [" << mRefPtr 3801 << "] FilterNode created (Type: " << int(mType) << ")"; 3802 } 3803 3804 inline bool RecordedDeferFilterInput::PlayEvent(Translator* aTranslator) const { 3805 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3806 if (!dt) { 3807 return false; 3808 } 3809 3810 Path* path = aTranslator->LookupPath(mPath); 3811 if (!path) { 3812 return false; 3813 } 3814 3815 RefPtr<FilterNode> node = dt->DeferFilterInput( 3816 path, *GenericPattern(mPattern, aTranslator), mSourceRect, mDestOffset, 3817 mOptions, mHasStrokeOptions ? &mStrokeOptions : nullptr); 3818 aTranslator->AddFilterNode(mRefPtr, node); 3819 return true; 3820 } 3821 3822 template <class S> 3823 void RecordedDeferFilterInput::Record(S& aStream) const { 3824 WriteElement(aStream, mRefPtr); 3825 WriteElement(aStream, mPath); 3826 RecordPatternData(aStream, mPattern); 3827 WriteElement(aStream, mSourceRect); 3828 WriteElement(aStream, mDestOffset); 3829 WriteElement(aStream, mOptions); 3830 WriteElement(aStream, mHasStrokeOptions); 3831 if (mHasStrokeOptions) { 3832 RecordStrokeOptions(aStream, mStrokeOptions); 3833 } 3834 } 3835 3836 template <class S> 3837 RecordedDeferFilterInput::RecordedDeferFilterInput(S& aStream) 3838 : RecordedEventDerived(DEFERFILTERINPUT) { 3839 ReadElement(aStream, mRefPtr); 3840 ReadElement(aStream, mPath); 3841 ReadPatternData(aStream, mPattern); 3842 ReadElement(aStream, mSourceRect); 3843 ReadElement(aStream, mDestOffset); 3844 ReadDrawOptions(aStream, mOptions); 3845 ReadElement(aStream, mHasStrokeOptions); 3846 if (mHasStrokeOptions) { 3847 ReadStrokeOptions(aStream, mStrokeOptions); 3848 } 3849 } 3850 3851 inline void RecordedDeferFilterInput::OutputSimpleEventInfo( 3852 std::stringstream& aStringStream) const { 3853 aStringStream << "DeferFilterInput[" << mRefPtr << "] (" << mPath << ") "; 3854 OutputSimplePatternInfo(mPattern, aStringStream); 3855 } 3856 3857 inline bool RecordedFilterNodeDestruction::PlayEvent( 3858 Translator* aTranslator) const { 3859 aTranslator->RemoveFilterNode(mRefPtr); 3860 return true; 3861 } 3862 3863 template <class S> 3864 void RecordedFilterNodeDestruction::Record(S& aStream) const { 3865 WriteElement(aStream, mRefPtr); 3866 } 3867 3868 template <class S> 3869 RecordedFilterNodeDestruction::RecordedFilterNodeDestruction(S& aStream) 3870 : RecordedEventDerived(FILTERNODEDESTRUCTION) { 3871 ReadElement(aStream, mRefPtr); 3872 } 3873 3874 inline void RecordedFilterNodeDestruction::OutputSimpleEventInfo( 3875 std::stringstream& aStringStream) const { 3876 aStringStream << "[" << mRefPtr << "] FilterNode Destroyed"; 3877 } 3878 3879 inline RecordedGradientStopsCreation::~RecordedGradientStopsCreation() { 3880 if (mDataOwned) { 3881 delete[] mStops; 3882 } 3883 } 3884 3885 inline bool RecordedGradientStopsCreation::PlayEvent( 3886 Translator* aTranslator) const { 3887 if (mNumStops > 0 && !mStops) { 3888 // Stops allocation failed 3889 return false; 3890 } 3891 3892 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3893 if (!dt) { 3894 return false; 3895 } 3896 3897 RefPtr<GradientStops> src = 3898 aTranslator->GetOrCreateGradientStops(dt, mStops, mNumStops, mExtendMode); 3899 aTranslator->AddGradientStops(mRefPtr, src); 3900 return true; 3901 } 3902 3903 template <class S> 3904 void RecordedGradientStopsCreation::Record(S& aStream) const { 3905 WriteElement(aStream, mRefPtr); 3906 WriteElement(aStream, mExtendMode); 3907 WriteElement(aStream, mNumStops); 3908 aStream.write((const char*)mStops, mNumStops * sizeof(GradientStop)); 3909 } 3910 3911 template <class S> 3912 RecordedGradientStopsCreation::RecordedGradientStopsCreation(S& aStream) 3913 : RecordedEventDerived(GRADIENTSTOPSCREATION), mDataOwned(true) { 3914 ReadElement(aStream, mRefPtr); 3915 ReadElementConstrained(aStream, mExtendMode, ExtendMode::CLAMP, 3916 ExtendMode::REFLECT); 3917 ReadElement(aStream, mNumStops); 3918 if (!aStream.good() || mNumStops <= 0) { 3919 return; 3920 } 3921 3922 mStops = new (fallible) GradientStop[mNumStops]; 3923 if (!mStops) { 3924 gfxCriticalNote 3925 << "RecordedGradientStopsCreation failed to allocate stops of size " 3926 << mNumStops; 3927 aStream.SetIsBad(); 3928 } else { 3929 aStream.read((char*)mStops, mNumStops * sizeof(GradientStop)); 3930 } 3931 } 3932 3933 inline void RecordedGradientStopsCreation::OutputSimpleEventInfo( 3934 std::stringstream& aStringStream) const { 3935 aStringStream << "[" << mRefPtr 3936 << "] GradientStops created (Stops: " << mNumStops << ")"; 3937 } 3938 3939 inline bool RecordedGradientStopsDestruction::PlayEvent( 3940 Translator* aTranslator) const { 3941 aTranslator->RemoveGradientStops(mRefPtr); 3942 return true; 3943 } 3944 3945 template <class S> 3946 void RecordedGradientStopsDestruction::Record(S& aStream) const { 3947 WriteElement(aStream, mRefPtr); 3948 } 3949 3950 template <class S> 3951 RecordedGradientStopsDestruction::RecordedGradientStopsDestruction(S& aStream) 3952 : RecordedEventDerived(GRADIENTSTOPSDESTRUCTION) { 3953 ReadElement(aStream, mRefPtr); 3954 } 3955 3956 inline void RecordedGradientStopsDestruction::OutputSimpleEventInfo( 3957 std::stringstream& aStringStream) const { 3958 aStringStream << "[" << mRefPtr << "] GradientStops Destroyed"; 3959 } 3960 3961 inline bool RecordedIntoLuminanceSource::PlayEvent( 3962 Translator* aTranslator) const { 3963 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 3964 if (!dt) { 3965 return false; 3966 } 3967 3968 RefPtr<SourceSurface> src = dt->IntoLuminanceSource(mLuminanceType, mOpacity); 3969 aTranslator->AddSourceSurface(mRefPtr, src); 3970 return true; 3971 } 3972 3973 template <class S> 3974 void RecordedIntoLuminanceSource::Record(S& aStream) const { 3975 WriteElement(aStream, mRefPtr); 3976 WriteElement(aStream, mLuminanceType); 3977 WriteElement(aStream, mOpacity); 3978 } 3979 3980 template <class S> 3981 RecordedIntoLuminanceSource::RecordedIntoLuminanceSource(S& aStream) 3982 : RecordedEventDerived(INTOLUMINANCE) { 3983 ReadElement(aStream, mRefPtr); 3984 ReadElementConstrained(aStream, mLuminanceType, LuminanceType::LUMINANCE, 3985 LuminanceType::LINEARRGB); 3986 ReadElement(aStream, mOpacity); 3987 } 3988 3989 inline void RecordedIntoLuminanceSource::OutputSimpleEventInfo( 3990 std::stringstream& aStringStream) const { 3991 aStringStream << "[" << mRefPtr << "] Into Luminance Source"; 3992 } 3993 3994 inline bool RecordedExtractSubrect::PlayEvent(Translator* aTranslator) const { 3995 SourceSurface* sourceSurf = aTranslator->LookupSourceSurface(mSourceSurface); 3996 if (!sourceSurf) { 3997 return false; 3998 } 3999 4000 RefPtr<SourceSurface> subSurf = sourceSurf->ExtractSubrect(mSubrect); 4001 if (!subSurf) { 4002 RefPtr<DrawTarget> dt = 4003 aTranslator->GetReferenceDrawTarget()->CreateSimilarDrawTarget( 4004 mSubrect.Size(), sourceSurf->GetFormat()); 4005 if (dt) { 4006 dt->CopySurface(sourceSurf, mSubrect, IntPoint()); 4007 subSurf = dt->Snapshot(); 4008 } 4009 } 4010 if (!subSurf) { 4011 return false; 4012 } 4013 4014 aTranslator->AddSourceSurface(mRefPtr, subSurf); 4015 return true; 4016 } 4017 4018 template <class S> 4019 void RecordedExtractSubrect::Record(S& aStream) const { 4020 WriteElement(aStream, mRefPtr); 4021 WriteElement(aStream, mSourceSurface); 4022 WriteElement(aStream, mSubrect); 4023 } 4024 4025 template <class S> 4026 RecordedExtractSubrect::RecordedExtractSubrect(S& aStream) 4027 : RecordedEventDerived(EXTRACTSUBRECT) { 4028 ReadElement(aStream, mRefPtr); 4029 ReadElement(aStream, mSourceSurface); 4030 ReadElement(aStream, mSubrect); 4031 } 4032 4033 inline void RecordedExtractSubrect::OutputSimpleEventInfo( 4034 std::stringstream& aStringStream) const { 4035 aStringStream << "[" << mRefPtr << "] Exract Subrect"; 4036 } 4037 4038 inline bool RecordedFlush::PlayEvent(Translator* aTranslator) const { 4039 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 4040 if (!dt) { 4041 return false; 4042 } 4043 4044 dt->Flush(); 4045 return true; 4046 } 4047 4048 template <class S> 4049 void RecordedFlush::Record(S& aStream) const {} 4050 4051 template <class S> 4052 RecordedFlush::RecordedFlush(S& aStream) : RecordedEventDerived(FLUSH) {} 4053 4054 inline void RecordedFlush::OutputSimpleEventInfo( 4055 std::stringstream& aStringStream) const { 4056 aStringStream << "Flush"; 4057 } 4058 4059 inline bool RecordedDetachAllSnapshots::PlayEvent( 4060 Translator* aTranslator) const { 4061 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 4062 if (!dt) { 4063 return false; 4064 } 4065 4066 dt->DetachAllSnapshots(); 4067 return true; 4068 } 4069 4070 template <class S> 4071 void RecordedDetachAllSnapshots::Record(S& aStream) const {} 4072 4073 template <class S> 4074 RecordedDetachAllSnapshots::RecordedDetachAllSnapshots(S& aStream) 4075 : RecordedEventDerived(DETACHALLSNAPSHOTS) {} 4076 4077 inline void RecordedDetachAllSnapshots::OutputSimpleEventInfo( 4078 std::stringstream& aStringStream) const { 4079 aStringStream << "DetachAllSnapshots"; 4080 } 4081 4082 inline bool RecordedSnapshot::PlayEvent(Translator* aTranslator) const { 4083 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 4084 if (!dt) { 4085 return false; 4086 } 4087 4088 RefPtr<SourceSurface> src = dt->Snapshot(); 4089 aTranslator->AddSourceSurface(mRefPtr, src); 4090 return true; 4091 } 4092 4093 template <class S> 4094 void RecordedSnapshot::Record(S& aStream) const { 4095 WriteElement(aStream, mRefPtr); 4096 } 4097 4098 template <class S> 4099 RecordedSnapshot::RecordedSnapshot(S& aStream) 4100 : RecordedEventDerived(SNAPSHOT) { 4101 ReadElement(aStream, mRefPtr); 4102 } 4103 4104 inline void RecordedSnapshot::OutputSimpleEventInfo( 4105 std::stringstream& aStringStream) const { 4106 aStringStream << "[" << mRefPtr << "] Snapshot Created"; 4107 } 4108 4109 inline bool RecordedFontData::PlayEvent(Translator* aTranslator) const { 4110 if (mData.empty()) { 4111 return false; 4112 } 4113 4114 RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource( 4115 mData.data(), mData.size(), mType, aTranslator->GetFontContext()); 4116 if (!fontResource) { 4117 return false; 4118 } 4119 4120 aTranslator->AddNativeFontResource(mFontDetails.fontDataKey, fontResource); 4121 return true; 4122 } 4123 4124 template <class S> 4125 void RecordedFontData::Record(S& aStream) const { 4126 MOZ_ASSERT(mGetFontFileDataSucceeded); 4127 4128 WriteElement(aStream, mType); 4129 WriteElement(aStream, mFontDetails.fontDataKey); 4130 WriteElement(aStream, mData.size()); 4131 mData.Write(aStream); 4132 } 4133 4134 inline void RecordedFontData::OutputSimpleEventInfo( 4135 std::stringstream& aStringStream) const { 4136 aStringStream << "Font Data of size " << mData.size(); 4137 } 4138 4139 inline void RecordedFontData::SetFontData(const uint8_t* aData, uint32_t aSize, 4140 uint32_t aIndex) { 4141 if (!mData.TryAssign(aData, aSize)) { 4142 mGetFontFileDataSucceeded = false; 4143 gfxCriticalNote 4144 << "RecordedFontData failed to allocate data for recording of size " 4145 << aSize; 4146 } 4147 mFontDetails.fontDataKey = SFNTData::GetUniqueKey(aData, aSize, 0, nullptr); 4148 mFontDetails.index = aIndex; 4149 } 4150 4151 inline bool RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) { 4152 if (!mGetFontFileDataSucceeded) { 4153 return false; 4154 } 4155 4156 fontDetails.fontDataKey = mFontDetails.fontDataKey; 4157 fontDetails.index = mFontDetails.index; 4158 return true; 4159 } 4160 4161 template <class S> 4162 RecordedFontData::RecordedFontData(S& aStream) 4163 : RecordedEventDerived(FONTDATA), mType(FontType::UNKNOWN) { 4164 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN); 4165 ReadElement(aStream, mFontDetails.fontDataKey); 4166 uint32_t dataSize = 0; 4167 ReadElement(aStream, dataSize); 4168 if (!dataSize || !aStream.good()) { 4169 return; 4170 } 4171 4172 if (!mData.Read(aStream, dataSize)) { 4173 gfxCriticalNote 4174 << "RecordedFontData failed to allocate data for playback of size " 4175 << dataSize; 4176 aStream.SetIsBad(); 4177 } 4178 } 4179 4180 inline RecordedFontDescriptor::~RecordedFontDescriptor() = default; 4181 4182 inline bool RecordedFontDescriptor::PlayEvent(Translator* aTranslator) const { 4183 RefPtr<UnscaledFont> font = Factory::CreateUnscaledFontFromFontDescriptor( 4184 mType, mData.data(), mData.size(), mIndex); 4185 if (!font) { 4186 gfxDevCrash(LogReason::InvalidFont) 4187 << "Failed creating UnscaledFont of type " << int(mType) 4188 << " from font descriptor"; 4189 return false; 4190 } 4191 4192 aTranslator->AddUnscaledFont(mRefPtr, font); 4193 return true; 4194 } 4195 4196 template <class S> 4197 void RecordedFontDescriptor::Record(S& aStream) const { 4198 MOZ_ASSERT(mHasDesc); 4199 WriteElement(aStream, mType); 4200 WriteElement(aStream, mRefPtr); 4201 WriteElement(aStream, mIndex); 4202 WriteElement(aStream, mData.size()); 4203 mData.Write(aStream); 4204 } 4205 4206 inline void RecordedFontDescriptor::OutputSimpleEventInfo( 4207 std::stringstream& aStringStream) const { 4208 aStringStream << "[" << mRefPtr << "] Font Descriptor"; 4209 } 4210 4211 inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData, 4212 uint32_t aSize, 4213 uint32_t aIndex) { 4214 mData.Assign(aData, aSize); 4215 mIndex = aIndex; 4216 } 4217 4218 template <class S> 4219 RecordedFontDescriptor::RecordedFontDescriptor(S& aStream) 4220 : RecordedEventDerived(FONTDESC) { 4221 ReadElementConstrained(aStream, mType, FontType::DWRITE, FontType::UNKNOWN); 4222 ReadElement(aStream, mRefPtr); 4223 ReadElement(aStream, mIndex); 4224 4225 size_t size = 0; 4226 ReadElement(aStream, size); 4227 if (!aStream.good()) { 4228 return; 4229 } 4230 if (size && !mData.Read(aStream, size)) { 4231 aStream.SetIsBad(); 4232 return; 4233 } 4234 } 4235 4236 inline bool RecordedUnscaledFontCreation::PlayEvent( 4237 Translator* aTranslator) const { 4238 NativeFontResource* fontResource = 4239 aTranslator->LookupNativeFontResource(mFontDataKey); 4240 if (!fontResource) { 4241 gfxDevCrash(LogReason::NativeFontResourceNotFound) 4242 << "NativeFontResource lookup failed for key |" << hexa(mFontDataKey) 4243 << "|."; 4244 return false; 4245 } 4246 4247 RefPtr<UnscaledFont> unscaledFont = fontResource->CreateUnscaledFont( 4248 mIndex, mInstanceData.data(), mInstanceData.size()); 4249 aTranslator->AddUnscaledFont(mRefPtr, unscaledFont); 4250 return true; 4251 } 4252 4253 template <class S> 4254 void RecordedUnscaledFontCreation::Record(S& aStream) const { 4255 WriteElement(aStream, mRefPtr); 4256 WriteElement(aStream, mFontDataKey); 4257 WriteElement(aStream, mIndex); 4258 WriteElement(aStream, mInstanceData.size()); 4259 mInstanceData.Write(aStream); 4260 } 4261 4262 inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo( 4263 std::stringstream& aStringStream) const { 4264 aStringStream << "[" << mRefPtr << "] UnscaledFont Created"; 4265 } 4266 4267 inline void RecordedUnscaledFontCreation::SetFontInstanceData( 4268 const uint8_t* aData, uint32_t aSize) { 4269 if (aSize) { 4270 mInstanceData.Assign(aData, aSize); 4271 } 4272 } 4273 4274 template <class S> 4275 RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream) 4276 : RecordedEventDerived(UNSCALEDFONTCREATION) { 4277 ReadElement(aStream, mRefPtr); 4278 ReadElement(aStream, mFontDataKey); 4279 ReadElement(aStream, mIndex); 4280 4281 size_t size = 0; 4282 ReadElement(aStream, size); 4283 if (!aStream.good()) { 4284 return; 4285 } 4286 if (size && !mInstanceData.Read(aStream, size)) { 4287 aStream.SetIsBad(); 4288 return; 4289 } 4290 } 4291 4292 inline bool RecordedUnscaledFontDestruction::PlayEvent( 4293 Translator* aTranslator) const { 4294 aTranslator->RemoveUnscaledFont(mRefPtr); 4295 return true; 4296 } 4297 4298 template <class S> 4299 void RecordedUnscaledFontDestruction::Record(S& aStream) const { 4300 WriteElement(aStream, mRefPtr); 4301 } 4302 4303 template <class S> 4304 RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(S& aStream) 4305 : RecordedEventDerived(UNSCALEDFONTDESTRUCTION) { 4306 ReadElement(aStream, mRefPtr); 4307 } 4308 4309 inline void RecordedUnscaledFontDestruction::OutputSimpleEventInfo( 4310 std::stringstream& aStringStream) const { 4311 aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed"; 4312 } 4313 4314 inline bool RecordedScaledFontCreation::PlayEvent( 4315 Translator* aTranslator) const { 4316 UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont); 4317 if (!unscaledFont) { 4318 gfxDevCrash(LogReason::UnscaledFontNotFound) 4319 << "UnscaledFont lookup failed for key |" << hexa(mUnscaledFont) 4320 << "|."; 4321 return false; 4322 } 4323 4324 RefPtr<ScaledFont> scaledFont = unscaledFont->CreateScaledFont( 4325 mGlyphSize, mInstanceData.data(), mInstanceData.size(), 4326 mVariations.data(), mVariations.size()); 4327 4328 aTranslator->AddScaledFont(mRefPtr, scaledFont); 4329 return true; 4330 } 4331 4332 template <class S> 4333 void RecordedScaledFontCreation::Record(S& aStream) const { 4334 WriteElement(aStream, mRefPtr); 4335 WriteElement(aStream, mUnscaledFont); 4336 WriteElement(aStream, mGlyphSize); 4337 WriteElement(aStream, mInstanceData.size()); 4338 mInstanceData.Write(aStream); 4339 WriteElement(aStream, mVariations.size()); 4340 mVariations.Write(aStream); 4341 } 4342 4343 inline void RecordedScaledFontCreation::OutputSimpleEventInfo( 4344 std::stringstream& aStringStream) const { 4345 aStringStream << "[" << mRefPtr << "] ScaledFont Created"; 4346 } 4347 4348 inline void RecordedScaledFontCreation::SetFontInstanceData( 4349 const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations, 4350 uint32_t aNumVariations) { 4351 if (aSize) { 4352 mInstanceData.Assign(aData, aSize); 4353 } 4354 if (aNumVariations) { 4355 mVariations.Assign(aVariations, aNumVariations); 4356 } 4357 } 4358 4359 template <class S> 4360 RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream) 4361 : RecordedEventDerived(SCALEDFONTCREATION) { 4362 ReadElement(aStream, mRefPtr); 4363 ReadElement(aStream, mUnscaledFont); 4364 ReadElement(aStream, mGlyphSize); 4365 4366 size_t size = 0; 4367 ReadElement(aStream, size); 4368 if (!aStream.good()) { 4369 return; 4370 } 4371 if (size && !mInstanceData.Read(aStream, size)) { 4372 aStream.SetIsBad(); 4373 return; 4374 } 4375 4376 size_t numVariations = 0; 4377 ReadElement(aStream, numVariations); 4378 if (!aStream.good()) { 4379 return; 4380 } 4381 if (numVariations && !mVariations.Read(aStream, numVariations)) { 4382 aStream.SetIsBad(); 4383 return; 4384 } 4385 } 4386 4387 inline bool RecordedScaledFontDestruction::PlayEvent( 4388 Translator* aTranslator) const { 4389 aTranslator->RemoveScaledFont(mRefPtr); 4390 return true; 4391 } 4392 4393 template <class S> 4394 void RecordedScaledFontDestruction::Record(S& aStream) const { 4395 WriteElement(aStream, mRefPtr); 4396 } 4397 4398 template <class S> 4399 RecordedScaledFontDestruction::RecordedScaledFontDestruction(S& aStream) 4400 : RecordedEventDerived(SCALEDFONTDESTRUCTION) { 4401 ReadElement(aStream, mRefPtr); 4402 } 4403 4404 inline void RecordedScaledFontDestruction::OutputSimpleEventInfo( 4405 std::stringstream& aStringStream) const { 4406 aStringStream << "[" << mRefPtr << "] ScaledFont Destroyed"; 4407 } 4408 4409 inline bool RecordedMaskSurface::PlayEvent(Translator* aTranslator) const { 4410 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 4411 if (!dt) { 4412 return false; 4413 } 4414 4415 SourceSurface* surface = aTranslator->LookupSourceSurface(mRefMask); 4416 if (!surface) { 4417 return false; 4418 } 4419 4420 dt->MaskSurface(*GenericPattern(mPattern, aTranslator), surface, mOffset, 4421 mOptions); 4422 return true; 4423 } 4424 4425 template <class S> 4426 void RecordedMaskSurface::Record(S& aStream) const { 4427 RecordPatternData(aStream, mPattern); 4428 WriteElement(aStream, mRefMask); 4429 WriteElement(aStream, mOffset); 4430 WriteElement(aStream, mOptions); 4431 } 4432 4433 template <class S> 4434 RecordedMaskSurface::RecordedMaskSurface(S& aStream) 4435 : RecordedEventDerived(MASKSURFACE) { 4436 ReadPatternData(aStream, mPattern); 4437 ReadElement(aStream, mRefMask); 4438 ReadElement(aStream, mOffset); 4439 ReadDrawOptions(aStream, mOptions); 4440 } 4441 4442 inline void RecordedMaskSurface::OutputSimpleEventInfo( 4443 std::stringstream& aStringStream) const { 4444 aStringStream << "MaskSurface (" << mRefMask << ") Offset: (" << mOffset.x 4445 << "x" << mOffset.y << ") Pattern: "; 4446 OutputSimplePatternInfo(mPattern, aStringStream); 4447 } 4448 4449 inline bool RecordedFilterNodeSetAttribute::PlayEvent( 4450 Translator* aTranslator) const { 4451 FilterNode* node = aTranslator->LookupFilterNode(mNode); 4452 if (!node) { 4453 return false; 4454 } 4455 4456 #define REPLAY_SET_ATTRIBUTE_CAST(type, cast, argtype) \ 4457 case ARGTYPE_##argtype: \ 4458 if (mPayload.size() < sizeof(type)) { \ 4459 return false; \ 4460 } \ 4461 node->SetAttribute(mIndex, cast(*(type*)mPayload.data())); \ 4462 break 4463 #define REPLAY_SET_ATTRIBUTE(type, argtype) \ 4464 REPLAY_SET_ATTRIBUTE_CAST(type, , argtype) 4465 4466 switch (mArgType) { 4467 REPLAY_SET_ATTRIBUTE_CAST(uint8_t, bool, BOOL); 4468 REPLAY_SET_ATTRIBUTE(uint32_t, UINT32); 4469 REPLAY_SET_ATTRIBUTE(Float, FLOAT); 4470 REPLAY_SET_ATTRIBUTE(Size, SIZE); 4471 REPLAY_SET_ATTRIBUTE(IntSize, INTSIZE); 4472 REPLAY_SET_ATTRIBUTE(IntPoint, INTPOINT); 4473 REPLAY_SET_ATTRIBUTE(Rect, RECT); 4474 REPLAY_SET_ATTRIBUTE(IntRect, INTRECT); 4475 REPLAY_SET_ATTRIBUTE(Point, POINT); 4476 REPLAY_SET_ATTRIBUTE(Matrix, MATRIX); 4477 REPLAY_SET_ATTRIBUTE(Matrix5x4, MATRIX5X4); 4478 REPLAY_SET_ATTRIBUTE(Point3D, POINT3D); 4479 REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR); 4480 case ARGTYPE_FLOAT_ARRAY: 4481 node->SetAttribute(mIndex, 4482 reinterpret_cast<const Float*>(mPayload.data()), 4483 mPayload.size() / sizeof(Float)); 4484 break; 4485 } 4486 4487 return true; 4488 } 4489 4490 template <class S> 4491 void RecordedFilterNodeSetAttribute::Record(S& aStream) const { 4492 WriteElement(aStream, mNode); 4493 WriteElement(aStream, mIndex); 4494 WriteElement(aStream, mArgType); 4495 WriteElement(aStream, mPayload.size()); 4496 mPayload.Write(aStream); 4497 } 4498 4499 template <class S> 4500 RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream) 4501 : RecordedEventDerived(FILTERNODESETATTRIBUTE) { 4502 ReadElement(aStream, mNode); 4503 ReadElement(aStream, mIndex); 4504 ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32, 4505 ArgType::ARGTYPE_FLOAT_ARRAY); 4506 size_t size = 0; 4507 ReadElement(aStream, size); 4508 if (!aStream.good()) { 4509 return; 4510 } 4511 4512 if (size && !mPayload.Read(aStream, size)) { 4513 aStream.SetIsBad(); 4514 return; 4515 } 4516 } 4517 4518 inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo( 4519 std::stringstream& aStringStream) const { 4520 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ")"; 4521 } 4522 4523 inline bool RecordedFilterNodeSetInput::PlayEvent( 4524 Translator* aTranslator) const { 4525 FilterNode* node = aTranslator->LookupFilterNode(mNode); 4526 if (!node) { 4527 return false; 4528 } 4529 4530 if (mInputFilter) { 4531 node->SetInput(mIndex, aTranslator->LookupFilterNode(mInputFilter)); 4532 } else { 4533 node->SetInput(mIndex, aTranslator->LookupSourceSurface(mInputSurface)); 4534 } 4535 4536 return true; 4537 } 4538 4539 template <class S> 4540 void RecordedFilterNodeSetInput::Record(S& aStream) const { 4541 WriteElement(aStream, mNode); 4542 WriteElement(aStream, mIndex); 4543 WriteElement(aStream, mInputFilter); 4544 WriteElement(aStream, mInputSurface); 4545 } 4546 4547 template <class S> 4548 RecordedFilterNodeSetInput::RecordedFilterNodeSetInput(S& aStream) 4549 : RecordedEventDerived(FILTERNODESETINPUT) { 4550 ReadElement(aStream, mNode); 4551 ReadElement(aStream, mIndex); 4552 ReadElement(aStream, mInputFilter); 4553 ReadElement(aStream, mInputSurface); 4554 } 4555 4556 inline void RecordedFilterNodeSetInput::OutputSimpleEventInfo( 4557 std::stringstream& aStringStream) const { 4558 aStringStream << "[" << mNode << "] SetAttribute (" << mIndex << ", "; 4559 4560 if (mInputFilter) { 4561 aStringStream << "Filter: " << mInputFilter; 4562 } else { 4563 aStringStream << "Surface: " << mInputSurface; 4564 } 4565 4566 aStringStream << ")"; 4567 } 4568 4569 inline bool RecordedLink::PlayEvent(Translator* aTranslator) const { 4570 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 4571 if (!dt) { 4572 return false; 4573 } 4574 dt->Link(mLocalDest.data(), mURI.data(), mRect); 4575 return true; 4576 } 4577 4578 template <class S> 4579 void RecordedLink::Record(S& aStream) const { 4580 WriteElement(aStream, mRect); 4581 WriteElement(aStream, mLocalDest.size()); 4582 mLocalDest.Write(aStream); 4583 WriteElement(aStream, mURI.size()); 4584 mURI.Write(aStream); 4585 } 4586 4587 template <class S> 4588 RecordedLink::RecordedLink(S& aStream) : RecordedEventDerived(LINK) { 4589 ReadElement(aStream, mRect); 4590 size_t localDestLen = 0; 4591 ReadElement(aStream, localDestLen); 4592 if (!aStream.good() || 4593 (localDestLen && !mLocalDest.Read(aStream, localDestLen))) { 4594 aStream.SetIsBad(); 4595 return; 4596 } 4597 size_t uriLen = 0; 4598 ReadElement(aStream, uriLen); 4599 if (!aStream.good() || (uriLen && !mURI.Read(aStream, uriLen))) { 4600 aStream.SetIsBad(); 4601 return; 4602 } 4603 } 4604 4605 inline void RecordedLink::OutputSimpleEventInfo( 4606 std::stringstream& aStringStream) const { 4607 if (mLocalDest.empty()) { 4608 aStringStream << "Link [" << mURI.data() << " @ " << mRect << "]"; 4609 } else { 4610 aStringStream << "Link [" << mLocalDest.data() << " / " << mURI.data() 4611 << " @ " << mRect << "]"; 4612 } 4613 } 4614 4615 inline bool RecordedDestination::PlayEvent(Translator* aTranslator) const { 4616 DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); 4617 if (!dt) { 4618 return false; 4619 } 4620 dt->Destination(mDestination.data(), mPoint); 4621 return true; 4622 } 4623 4624 template <class S> 4625 void RecordedDestination::Record(S& aStream) const { 4626 WriteElement(aStream, mPoint); 4627 WriteElement(aStream, mDestination.size()); 4628 mDestination.Write(aStream); 4629 } 4630 4631 template <class S> 4632 RecordedDestination::RecordedDestination(S& aStream) 4633 : RecordedEventDerived(DESTINATION) { 4634 ReadElement(aStream, mPoint); 4635 size_t len = 0; 4636 ReadElement(aStream, len); 4637 if (!aStream.good() || (len && !mDestination.Read(aStream, len))) { 4638 aStream.SetIsBad(); 4639 return; 4640 } 4641 } 4642 4643 inline void RecordedDestination::OutputSimpleEventInfo( 4644 std::stringstream& aStringStream) const { 4645 aStringStream << "Destination [" << mDestination.data() << " @ " << mPoint 4646 << "]"; 4647 } 4648 4649 #define FOR_EACH_EVENT(f) \ 4650 f(DRAWTARGETCREATION, RecordedDrawTargetCreation); \ 4651 f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction); \ 4652 f(SETCURRENTDRAWTARGET, RecordedSetCurrentDrawTarget); \ 4653 f(FILLRECT, RecordedFillRect); \ 4654 f(STROKERECT, RecordedStrokeRect); \ 4655 f(STROKELINE, RecordedStrokeLine); \ 4656 f(STROKECIRCLE, RecordedStrokeCircle); \ 4657 f(CLEARRECT, RecordedClearRect); \ 4658 f(COPYSURFACE, RecordedCopySurface); \ 4659 f(SETPERMITSUBPIXELAA, RecordedSetPermitSubpixelAA); \ 4660 f(SETTRANSFORM, RecordedSetTransform); \ 4661 f(PUSHCLIPRECT, RecordedPushClipRect); \ 4662 f(PUSHCLIP, RecordedPushClip); \ 4663 f(POPCLIP, RecordedPopClip); \ 4664 f(REMOVEALLCLIPS, RecordedRemoveAllClips); \ 4665 f(FILL, RecordedFill); \ 4666 f(FILLCIRCLE, RecordedFillCircle); \ 4667 f(FILLGLYPHS, RecordedFillGlyphs); \ 4668 f(STROKEGLYPHS, RecordedStrokeGlyphs); \ 4669 f(MASK, RecordedMask); \ 4670 f(STROKE, RecordedStroke); \ 4671 f(DRAWSURFACE, RecordedDrawSurface); \ 4672 f(DRAWSURFACEDESCRIPTOR, RecordedDrawSurfaceDescriptor); \ 4673 f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \ 4674 f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \ 4675 f(DRAWSHADOW, RecordedDrawShadow); \ 4676 f(DRAWFILTER, RecordedDrawFilter); \ 4677 f(PATHCREATION, RecordedPathCreation); \ 4678 f(PATHDESTRUCTION, RecordedPathDestruction); \ 4679 f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \ 4680 f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \ 4681 f(FILTERNODECREATION, RecordedFilterNodeCreation); \ 4682 f(DEFERFILTERINPUT, RecordedDeferFilterInput); \ 4683 f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \ 4684 f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \ 4685 f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \ 4686 f(SNAPSHOT, RecordedSnapshot); \ 4687 f(SCALEDFONTCREATION, RecordedScaledFontCreation); \ 4688 f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \ 4689 f(MASKSURFACE, RecordedMaskSurface); \ 4690 f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \ 4691 f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \ 4692 f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \ 4693 f(CREATECLIPPEDDRAWTARGET, RecordedCreateClippedDrawTarget); \ 4694 f(CREATEDRAWTARGETFORFILTER, RecordedCreateDrawTargetForFilter); \ 4695 f(FONTDATA, RecordedFontData); \ 4696 f(FONTDESC, RecordedFontDescriptor); \ 4697 f(PUSHLAYER, RecordedPushLayer); \ 4698 f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend); \ 4699 f(POPLAYER, RecordedPopLayer); \ 4700 f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation); \ 4701 f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction); \ 4702 f(INTOLUMINANCE, RecordedIntoLuminanceSource); \ 4703 f(EXTRACTSUBRECT, RecordedExtractSubrect); \ 4704 f(EXTERNALSURFACECREATION, RecordedExternalSurfaceCreation); \ 4705 f(FLUSH, RecordedFlush); \ 4706 f(DETACHALLSNAPSHOTS, RecordedDetachAllSnapshots); \ 4707 f(OPTIMIZESOURCESURFACE, RecordedOptimizeSourceSurface); \ 4708 f(LINK, RecordedLink); \ 4709 f(DESTINATION, RecordedDestination); 4710 4711 #define DO_WITH_EVENT_TYPE(_typeenum, _class) \ 4712 case _typeenum: { \ 4713 auto e = _class(aStream); \ 4714 return aAction(&e); \ 4715 } 4716 4717 template <class S> 4718 bool RecordedEvent::DoWithEvent( 4719 S& aStream, EventType aType, 4720 const std::function<bool(RecordedEvent*)>& aAction) { 4721 switch (aType) { 4722 FOR_EACH_EVENT(DO_WITH_EVENT_TYPE) 4723 default: 4724 return false; 4725 } 4726 } 4727 4728 } // namespace gfx 4729 } // namespace mozilla 4730 4731 #endif