Bug 1617708. Make ClippedDrawTarget use destination DT.
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Fri, 27 Mar 2020 03:15:05 +0000
changeset 520694 0e08a1d7fb078cc36882b737f00da2f48f9349a6
parent 520693 f8086519b2089d2809822374c089d94a88b75769
child 520695 62b434d3602a043ae16ddb098f3b01c46a883156
push id111256
push userjmuizelaar@mozilla.com
push dateFri, 27 Mar 2020 03:17:32 +0000
treeherderautoland@0e08a1d7fb07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1617708
milestone76.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 1617708. Make ClippedDrawTarget use destination DT. By using the destination DT we will use the correct offset during playback instead of the offset of the reference target. Differential Revision: https://phabricator.services.mozilla.com/D68495
gfx/2d/DrawTargetRecording.cpp
gfx/2d/DrawTargetWrapAndRecord.cpp
gfx/2d/RecordedEventImpl.h
layout/reftests/svg/filters/nested-filter-ref.html
layout/reftests/svg/filters/nested-filter.html
layout/reftests/svg/filters/reftest.list
--- a/gfx/2d/DrawTargetRecording.cpp
+++ b/gfx/2d/DrawTargetRecording.cpp
@@ -551,17 +551,17 @@ bool DrawTargetRecording::CanCreateSimil
   return mFinalDT->CanCreateSimilarDrawTarget(aSize, aFormat);
 }
 
 RefPtr<DrawTarget> DrawTargetRecording::CreateClippedDrawTarget(
     const Rect& aBounds, SurfaceFormat aFormat) {
   RefPtr<DrawTarget> similarDT;
   similarDT = new DrawTargetRecording(this, mRect, aFormat);
   mRecorder->RecordEvent(
-      RecordedCreateClippedDrawTarget(similarDT.get(), aBounds, aFormat));
+      RecordedCreateClippedDrawTarget(this, similarDT.get(), aBounds, aFormat));
   similarDT->SetTransform(mTransform);
   return similarDT;
 }
 
 already_AddRefed<DrawTarget>
 DrawTargetRecording::CreateSimilarDrawTargetForFilter(
     const IntSize& aMaxSize, SurfaceFormat aFormat, FilterNode* aFilter,
     FilterNode* aSource, const Rect& aSourceRect, const Point& aDestPoint) {
--- a/gfx/2d/DrawTargetWrapAndRecord.cpp
+++ b/gfx/2d/DrawTargetWrapAndRecord.cpp
@@ -649,17 +649,17 @@ bool DrawTargetWrapAndRecord::CanCreateS
 
 RefPtr<DrawTarget> DrawTargetWrapAndRecord::CreateClippedDrawTarget(
     const Rect& aBounds, SurfaceFormat aFormat) {
   RefPtr<DrawTarget> similarDT;
   RefPtr<DrawTarget> innerDT =
       mFinalDT->CreateClippedDrawTarget(aBounds, aFormat);
   similarDT = new DrawTargetWrapAndRecord(this->mRecorder, innerDT);
   mRecorder->RecordEvent(
-      RecordedCreateClippedDrawTarget(similarDT.get(), aBounds, aFormat));
+      RecordedCreateClippedDrawTarget(this, similarDT.get(), aBounds, aFormat));
   return similarDT;
 }
 
 already_AddRefed<PathBuilder> DrawTargetWrapAndRecord::CreatePathBuilder(
     FillRule aFillRule) const {
   RefPtr<PathBuilder> builder = mFinalDT->CreatePathBuilder(aFillRule);
   return MakeAndAddRef<PathBuilderRecording>(builder, aFillRule);
 }
--- a/gfx/2d/RecordedEventImpl.h
+++ b/gfx/2d/RecordedEventImpl.h
@@ -128,21 +128,21 @@ class RecordedCreateSimilarDrawTarget
  private:
   friend class RecordedEvent;
 
   template <class S>
   MOZ_IMPLICIT RecordedCreateSimilarDrawTarget(S& aStream);
 };
 
 class RecordedCreateClippedDrawTarget
-    : public RecordedEventDerived<RecordedCreateClippedDrawTarget> {
+    : public RecordedDrawingEvent<RecordedCreateClippedDrawTarget> {
  public:
-  RecordedCreateClippedDrawTarget(ReferencePtr aRefPtr, const Rect& aBounds,
-                                  SurfaceFormat aFormat)
-      : RecordedEventDerived(CREATECLIPPEDDRAWTARGET),
+  RecordedCreateClippedDrawTarget(DrawTarget* aDT, ReferencePtr aRefPtr,
+                                  const Rect& aBounds, SurfaceFormat aFormat)
+      : RecordedDrawingEvent(CREATECLIPPEDDRAWTARGET, aDT),
         mRefPtr(aRefPtr),
         mBounds(aBounds),
         mFormat(aFormat) {}
 
   bool PlayEvent(Translator* aTranslator) const override;
 
   template <class S>
   void Record(S& aStream) const;
@@ -2062,40 +2062,44 @@ inline bool RecordedCreateDrawTargetForF
   }
 
   aTranslator->AddDrawTarget(mRefPtr, newDT);
   return true;
 }
 
 inline bool RecordedCreateClippedDrawTarget::PlayEvent(
     Translator* aTranslator) const {
-  RefPtr<DrawTarget> newDT =
-      aTranslator->GetReferenceDrawTarget()->CreateClippedDrawTarget(mBounds,
-                                                                     mFormat);
+  DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
+  if (!dt) {
+    return false;
+  }
+
+  RefPtr<DrawTarget> newDT = dt->CreateClippedDrawTarget(mBounds, mFormat);
 
   // If we couldn't create a DrawTarget this will probably cause us to crash
   // with nullptr later in the playback, so return false to abort.
   if (!newDT) {
     return false;
   }
 
   aTranslator->AddDrawTarget(mRefPtr, newDT);
   return true;
 }
 
 template <class S>
 void RecordedCreateClippedDrawTarget::Record(S& aStream) const {
+  RecordedDrawingEvent::Record(aStream);
   WriteElement(aStream, mRefPtr);
   WriteElement(aStream, mBounds);
   WriteElement(aStream, mFormat);
 }
 
 template <class S>
 RecordedCreateClippedDrawTarget::RecordedCreateClippedDrawTarget(S& aStream)
-    : RecordedEventDerived(CREATECLIPPEDDRAWTARGET) {
+    : RecordedDrawingEvent(CREATECLIPPEDDRAWTARGET, aStream) {
   ReadElement(aStream, mRefPtr);
   ReadElement(aStream, mBounds);
   ReadElementConstrained(aStream, mFormat, SurfaceFormat::A8R8G8B8_UINT32,
                          SurfaceFormat::UNKNOWN);
 }
 
 inline void RecordedCreateClippedDrawTarget::OutputSimpleEventInfo(
     std::stringstream& aStringStream) const {
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/nested-filter-ref.html
@@ -0,0 +1,14 @@
+<html style="background: red">
+<body>
+  <svg height="100px" width="100px">
+    <g transform="translate(0, 25)">>
+      <defs>
+        <mask id="m" maskUnits="userSpaceOnUse">
+          <rect x=10 y=10 width=51 height=45 fill="white"></rect>
+        </mask>
+      </defs>
+      <rect fill="yellow" x=0 y=0 width=100 height=100 mask="url(#m)"></rect>
+    </g>
+  </svg>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/nested-filter.html
@@ -0,0 +1,23 @@
+<html style="background: red">
+<body>
+  <svg height="100px" width="100px">
+    <defs>
+      <filter filterUnits="userSpaceOnUse" id="merge" color-interpolation-filters="sRGB">
+        <feMerge>
+          <feMergeNode in="SourceGraphic"></feMergeNode>
+        </feMerge>
+      </filter>
+    </defs>
+    <g filter="url(#merge)">
+      <g transform="translate(0, 25)">>
+        <defs>
+          <mask id="m" maskUnits="userSpaceOnUse">
+            <rect x=10 y=10 width=51 height=45 fill="white"></rect>
+          </mask>
+        </defs>
+        <rect fill="yellow" x=0 y=0 width=100 height=100 mask="url(#m)"></rect>
+      </g>
+    </g>
+  </svg>
+</body>
+</html>
--- a/layout/reftests/svg/filters/reftest.list
+++ b/layout/reftests/svg/filters/reftest.list
@@ -130,8 +130,9 @@ fuzzy(0-2,0-2659) skip-if(d2d) == feSpec
 == feTurbulence-offset.svg feTurbulence-offset-ref.svg
 fuzzy(0-1,0-10000) == feTurbulence-zero-baseFreq-01.svg feTurbulence-zero-baseFreq-01-ref.svg
 != feTurbulence-zero-baseFreq-02.svg about:blank
 
 == outside-sourcegraphic-1.svg outside-sourcegraphic-ref.svg
 # These failures are caused by bug 1586055
 fails-if(webrender) == outside-sourcegraphic-2.svg outside-sourcegraphic-ref.svg
 fails-if(webrender) == outside-sourcegraphic-3.svg outside-sourcegraphic-ref.svg
+== nested-filter.html nested-filter-ref.html