Bug 454059 - Support Link in DrawTargetRecording and playback. r=jrmuizel
authorJonathan Kew <jkew@mozilla.com>
Tue, 11 May 2021 17:00:29 +0000
changeset 579406 d23a00ef79accfd49223199bf0d62a4639c300a4
parent 579405 d4d8d352b8eb49873a300ac9e09e6fc4b5e09f81
child 579407 47fc505e89a85d56d6ff8f3d363f99d97468bcec
push id142975
push userjkew@mozilla.com
push dateTue, 11 May 2021 17:03:25 +0000
treeherderautoland@26b31c2612b4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs454059
milestone90.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 454059 - Support Link in DrawTargetRecording and playback. r=jrmuizel Differential Revision: https://phabricator.services.mozilla.com/D114205
gfx/2d/DrawTargetRecording.cpp
gfx/2d/DrawTargetRecording.h
gfx/2d/RecordedEvent.cpp
gfx/2d/RecordedEvent.h
gfx/2d/RecordedEventImpl.h
--- a/gfx/2d/DrawTargetRecording.cpp
+++ b/gfx/2d/DrawTargetRecording.cpp
@@ -193,16 +193,20 @@ DrawTargetRecording::DrawTargetRecording
     : mRecorder(aDT->mRecorder), mFinalDT(aDT->mFinalDT), mRect(aRect) {
   mFormat = aFormat;
 }
 
 DrawTargetRecording::~DrawTargetRecording() {
   mRecorder->RecordEvent(RecordedDrawTargetDestruction(ReferencePtr(this)));
 }
 
+void DrawTargetRecording::Link(const char* aDestination, const Rect& aRect) {
+  mRecorder->RecordEvent(RecordedLink(this, aDestination, aRect));
+}
+
 void DrawTargetRecording::FillRect(const Rect& aRect, const Pattern& aPattern,
                                    const DrawOptions& aOptions) {
   EnsurePatternDependenciesStored(aPattern);
 
   mRecorder->RecordEvent(RecordedFillRect(this, aRect, aPattern, aOptions));
 }
 
 void DrawTargetRecording::StrokeRect(const Rect& aRect, const Pattern& aPattern,
--- a/gfx/2d/DrawTargetRecording.h
+++ b/gfx/2d/DrawTargetRecording.h
@@ -24,16 +24,18 @@ class DrawTargetRecording : public DrawT
   virtual DrawTargetType GetType() const override {
     return mFinalDT->GetType();
   }
   virtual BackendType GetBackendType() const override {
     return BackendType::RECORDING;
   }
   virtual bool IsRecording() const override { return true; }
 
+  virtual void Link(const char* aDestination, const Rect& aRect) override;
+
   virtual already_AddRefed<SourceSurface> Snapshot() override;
   virtual already_AddRefed<SourceSurface> IntoLuminanceSource(
       LuminanceType aLuminanceType, float aOpacity) override;
 
   virtual void DetachAllSnapshots() override;
 
   virtual IntSize GetSize() const override { return mRect.Size(); }
   virtual IntRect GetRect() const override { return mRect; }
--- a/gfx/2d/RecordedEvent.cpp
+++ b/gfx/2d/RecordedEvent.cpp
@@ -110,16 +110,18 @@ std::string RecordedEvent::GetEventName(
     case POPLAYER:
       return "PopLayer";
     case UNSCALEDFONTCREATION:
       return "UnscaledFontCreation";
     case UNSCALEDFONTDESTRUCTION:
       return "UnscaledFontDestruction";
     case EXTERNALSURFACECREATION:
       return "ExternalSourceSurfaceCreation";
+    case LINK:
+      return "Link";
     default:
       return "Unknown";
   }
 }
 
 template <class S>
 void RecordedEvent::RecordUnscaledFontImpl(UnscaledFont* aUnscaledFont,
                                            S& aOutput) {
--- a/gfx/2d/RecordedEvent.h
+++ b/gfx/2d/RecordedEvent.h
@@ -25,17 +25,17 @@ const uint32_t kMagicInt = 0xc001feed;
 
 // A change in major revision means a change in event binary format, causing
 // loss of backwards compatibility. Old streams will not work in a player
 // using a newer major revision. And new streams will not work in a player
 // using an older major revision.
 const uint16_t kMajorRevision = 10;
 // A change in minor revision means additions of new events. New streams will
 // not play in older players.
-const uint16_t kMinorRevision = 1;
+const uint16_t kMinorRevision = 2;
 
 struct ReferencePtr {
   ReferencePtr() : mLongPtr(0) {}
 
   MOZ_IMPLICIT ReferencePtr(const void* aLongPtr)
       : mLongPtr(uint64_t(aLongPtr)) {}
 
   template <typename T>
@@ -386,16 +386,17 @@ class RecordedEvent {
     POPLAYER,
     UNSCALEDFONTCREATION,
     UNSCALEDFONTDESTRUCTION,
     INTOLUMINANCE,
     EXTERNALSURFACECREATION,
     FLUSH,
     DETACHALLSNAPSHOTS,
     OPTIMIZESOURCESURFACE,
+    LINK,
     LAST,
   };
 
   virtual ~RecordedEvent() = default;
 
   static std::string GetEventName(EventType aType);
 
   /**
--- a/gfx/2d/RecordedEventImpl.h
+++ b/gfx/2d/RecordedEventImpl.h
@@ -1525,16 +1525,40 @@ class RecordedFilterNodeSetInput
   uint32_t mIndex;
   ReferencePtr mInputFilter;
   ReferencePtr mInputSurface;
 
   template <class S>
   MOZ_IMPLICIT RecordedFilterNodeSetInput(S& aStream);
 };
 
+class RecordedLink : public RecordedDrawingEvent<RecordedLink> {
+ public:
+  RecordedLink(DrawTarget* aDT, const char* aDestination, const Rect& aRect)
+      : RecordedDrawingEvent(LINK, aDT),
+        mDestination(aDestination),
+        mRect(aRect) {}
+
+  bool PlayEvent(Translator* aTranslator) const override;
+  template <class S>
+  void Record(S& aStream) const;
+  void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
+
+  std::string GetName() const override { return "Link"; }
+
+ private:
+  friend class RecordedEvent;
+
+  std::string mDestination;
+  Rect mRect;
+
+  template <class S>
+  MOZ_IMPLICIT RecordedLink(S& aStream);
+};
+
 static std::string NameFromBackend(BackendType aType) {
   switch (aType) {
     case BackendType::NONE:
       return "None";
     case BackendType::DIRECT2D:
       return "Direct2D";
     default:
       return "Unknown";
@@ -3859,16 +3883,52 @@ inline void RecordedFilterNodeSetInput::
     aStringStream << "Filter: " << mInputFilter;
   } else {
     aStringStream << "Surface: " << mInputSurface;
   }
 
   aStringStream << ")";
 }
 
+inline bool RecordedLink::PlayEvent(Translator* aTranslator) const {
+  DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
+  if (!dt) {
+    return false;
+  }
+  dt->Link(mDestination.c_str(), mRect);
+  return true;
+}
+
+template <class S>
+void RecordedLink::Record(S& aStream) const {
+  RecordedDrawingEvent::Record(aStream);
+  WriteElement(aStream, mRect);
+  uint32_t len = mDestination.length();
+  WriteElement(aStream, len);
+  if (len) {
+    aStream.write(mDestination.data(), len);
+  }
+}
+
+template <class S>
+RecordedLink::RecordedLink(S& aStream) : RecordedDrawingEvent(LINK, aStream) {
+  ReadElement(aStream, mRect);
+  uint32_t len;
+  ReadElement(aStream, len);
+  mDestination.resize(size_t(len));
+  if (len && aStream.good()) {
+    aStream.read(&mDestination.front(), len);
+  }
+}
+
+inline void RecordedLink::OutputSimpleEventInfo(
+    std::stringstream& aStringStream) const {
+  aStringStream << "Link [" << mDestination << " @ " << mRect << "]";
+}
+
 #define FOR_EACH_EVENT(f)                                          \
   f(DRAWTARGETCREATION, RecordedDrawTargetCreation);               \
   f(DRAWTARGETDESTRUCTION, RecordedDrawTargetDestruction);         \
   f(FILLRECT, RecordedFillRect);                                   \
   f(STROKERECT, RecordedStrokeRect);                               \
   f(STROKELINE, RecordedStrokeLine);                               \
   f(CLEARRECT, RecordedClearRect);                                 \
   f(COPYSURFACE, RecordedCopySurface);                             \
@@ -3907,17 +3967,18 @@ inline void RecordedFilterNodeSetInput::
   f(PUSHLAYERWITHBLEND, RecordedPushLayerWithBlend);               \
   f(POPLAYER, RecordedPopLayer);                                   \
   f(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation);           \
   f(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction);     \
   f(INTOLUMINANCE, RecordedIntoLuminanceSource);                   \
   f(EXTERNALSURFACECREATION, RecordedExternalSurfaceCreation);     \
   f(FLUSH, RecordedFlush);                                         \
   f(DETACHALLSNAPSHOTS, RecordedDetachAllSnapshots);               \
-  f(OPTIMIZESOURCESURFACE, RecordedOptimizeSourceSurface);
+  f(OPTIMIZESOURCESURFACE, RecordedOptimizeSourceSurface);         \
+  f(LINK, RecordedLink);
 
 #define DO_WITH_EVENT_TYPE(_typeenum, _class) \
   case _typeenum: {                           \
     auto e = _class(aStream);                 \
     return aAction(&e);                       \
   }
 
 template <class S>