Don't cache SourceSurface's in FilterNodeSoftware (bug 1425056, r=mstange) draft
authorRyan Hunt <rhunt@eqrion.net>
Mon, 18 Dec 2017 12:46:09 -0600
changeset 713690 9550bb5ccfef0429a1fe8ab93709fe82358216cd
parent 713689 a58a3dc0dad47041c1c631f67b8fe247425ace95
child 713691 0f82c1eeef3f7aa64c07d2125c153c37a4a7a004
push id93735
push userbmo:rhunt@eqrion.net
push dateWed, 20 Dec 2017 22:39:00 +0000
reviewersmstange
bugs1425056
milestone59.0a1
Don't cache SourceSurface's in FilterNodeSoftware (bug 1425056, r=mstange) Caching SourceSurfaces on a filter node is not thread safe to multiple threads executing the same filter node at the same time. We could add a mutex to every filter node and guard on that, but I think it makes sense to just remove the caching for now. I'm open to readding this, if this proves to be a problem. MozReview-Commit-ID: Ca38WlG3V89
gfx/2d/FilterNodeSoftware.cpp
gfx/2d/FilterNodeSoftware.h
--- a/gfx/2d/FilterNodeSoftware.cpp
+++ b/gfx/2d/FilterNodeSoftware.cpp
@@ -618,63 +618,17 @@ already_AddRefed<DataSourceSurface>
 FilterNodeSoftware::GetOutput(const IntRect &aRect)
 {
   MOZ_ASSERT(GetOutputRectInRect(aRect).Contains(aRect));
 
   if (aRect.Overflows()) {
     return nullptr;
   }
 
-  if (!mCachedRect.Contains(aRect)) {
-    RequestRect(aRect);
-    mCachedOutput = Render(mRequestedRect);
-    if (!mCachedOutput) {
-      mCachedRect = IntRect();
-      mRequestedRect = IntRect();
-      return nullptr;
-    }
-    mCachedRect = mRequestedRect;
-    mRequestedRect = IntRect();
-  } else {
-    MOZ_ASSERT(mCachedOutput, "cached rect but no cached output?");
-  }
-  return GetDataSurfaceInRect(mCachedOutput, mCachedRect, aRect, EDGE_MODE_NONE);
-}
-
-void
-FilterNodeSoftware::RequestRect(const IntRect &aRect)
-{
-  if (mRequestedRect.Contains(aRect)) {
-    // Bail out now. Otherwise pathological filters can spend time exponential
-    // in the number of primitives, e.g. if each primitive takes the
-    // previous primitive as its two inputs.
-    return;
-  }
-  mRequestedRect = mRequestedRect.Union(aRect);
-  RequestFromInputsForRect(aRect);
-}
-
-void
-FilterNodeSoftware::RequestInputRect(uint32_t aInputEnumIndex, const IntRect &aRect)
-{
-  if (aRect.Overflows()) {
-    return;
-  }
-
-  int32_t inputIndex = InputIndex(aInputEnumIndex);
-  if (inputIndex < 0 || (uint32_t)inputIndex >= NumberOfSetInputs()) {
-    gfxDevCrash(LogReason::FilterInputError) << "Invalid input " << inputIndex << " vs. " << NumberOfSetInputs();
-    return;
-  }
-  if (mInputSurfaces[inputIndex]) {
-    return;
-  }
-  RefPtr<FilterNodeSoftware> filter = mInputFilters[inputIndex];
-  MOZ_ASSERT(filter, "missing input");
-  filter->RequestRect(filter->GetOutputRectInRect(aRect));
+  return Render(aRect);
 }
 
 SurfaceFormat
 FilterNodeSoftware::DesiredFormat(SurfaceFormat aCurrentFormat,
                                   FormatHint aFormatHint)
 {
   if (aCurrentFormat == SurfaceFormat::A8 && aFormatHint == CAN_HANDLE_A8) {
     return SurfaceFormat::A8;
@@ -823,60 +777,18 @@ FilterNodeSoftware::GetInputRectInRect(u
 }
 
 size_t
 FilterNodeSoftware::NumberOfSetInputs()
 {
   return std::max(mInputSurfaces.size(), mInputFilters.size());
 }
 
-void
-FilterNodeSoftware::AddInvalidationListener(FilterInvalidationListener* aListener)
-{
-  MOZ_ASSERT(aListener, "null listener");
-  mInvalidationListeners.push_back(aListener);
-}
-
-void
-FilterNodeSoftware::RemoveInvalidationListener(FilterInvalidationListener* aListener)
-{
-  MOZ_ASSERT(aListener, "null listener");
-  std::vector<FilterInvalidationListener*>::iterator it =
-    std::find(mInvalidationListeners.begin(), mInvalidationListeners.end(), aListener);
-  mInvalidationListeners.erase(it);
-}
-
-void
-FilterNodeSoftware::FilterInvalidated(FilterNodeSoftware* aFilter)
-{
-  Invalidate();
-}
-
-void
-FilterNodeSoftware::Invalidate()
-{
-  mCachedOutput = nullptr;
-  mCachedRect = IntRect();
-  for (std::vector<FilterInvalidationListener*>::iterator it = mInvalidationListeners.begin();
-       it != mInvalidationListeners.end(); it++) {
-    (*it)->FilterInvalidated(this);
-  }
-}
-
 FilterNodeSoftware::~FilterNodeSoftware()
 {
-  MOZ_ASSERT(!mInvalidationListeners.size(),
-             "All invalidation listeners should have unsubscribed themselves by now!");
-
-  for (std::vector<RefPtr<FilterNodeSoftware> >::iterator it = mInputFilters.begin();
-       it != mInputFilters.end(); it++) {
-    if (*it) {
-      (*it)->RemoveInvalidationListener(this);
-    }
-  }
 }
 
 void
 FilterNodeSoftware::SetInput(uint32_t aIndex, FilterNode *aFilter)
 {
   if (aFilter && aFilter->GetBackendType() != FILTER_BACKEND_SOFTWARE) {
     MOZ_ASSERT(false, "can only take software filters as inputs");
     return;
@@ -900,28 +812,21 @@ FilterNodeSoftware::SetInput(uint32_t aI
     gfxDevCrash(LogReason::FilterInputSet) << "Invalid set " << inputIndex;
     return;
   }
   if ((uint32_t)inputIndex >= NumberOfSetInputs()) {
     mInputSurfaces.resize(inputIndex + 1);
     mInputFilters.resize(inputIndex + 1);
   }
   mInputSurfaces[inputIndex] = aSurface;
-  if (mInputFilters[inputIndex]) {
-    mInputFilters[inputIndex]->RemoveInvalidationListener(this);
-  }
-  if (aFilter) {
-    aFilter->AddInvalidationListener(this);
-  }
   mInputFilters[inputIndex] = aFilter;
   if (!aSurface && !aFilter && (size_t)inputIndex == NumberOfSetInputs()) {
     mInputSurfaces.resize(inputIndex);
     mInputFilters.resize(inputIndex);
   }
-  Invalidate();
 }
 
 FilterNodeBlendSoftware::FilterNodeBlendSoftware()
  : mBlendMode(BLEND_MODE_MULTIPLY)
 {}
 
 int32_t
 FilterNodeBlendSoftware::InputIndex(uint32_t aInputEnumIndex)
@@ -933,17 +838,16 @@ FilterNodeBlendSoftware::InputIndex(uint
   }
 }
 
 void
 FilterNodeBlendSoftware::SetAttribute(uint32_t aIndex, uint32_t aBlendMode)
 {
   MOZ_ASSERT(aIndex == ATT_BLEND_BLENDMODE);
   mBlendMode = static_cast<BlendMode>(aBlendMode);
-  Invalidate();
 }
 
 static CompositionOp ToBlendOp(BlendMode aOp)
 {
   switch (aOp) {
   case BLEND_MODE_MULTIPLY:
     return CompositionOp::OP_MULTIPLY;
   case BLEND_MODE_SCREEN:
@@ -1037,23 +941,16 @@ FilterNodeBlendSoftware::Render(const In
   }
 
   Rect r(0, 0, size.width, size.height);
   dt->DrawSurface(input2, r, r, DrawSurfaceOptions(), DrawOptions(1.0f, ToBlendOp(mBlendMode)));
   dt->Flush();
   return target.forget();
 }
 
-void
-FilterNodeBlendSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_BLEND_IN, aRect);
-  RequestInputRect(IN_BLEND_IN2, aRect);
-}
-
 IntRect
 FilterNodeBlendSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   return GetInputRectInRect(IN_BLEND_IN, aRect).Union(
     GetInputRectInRect(IN_BLEND_IN2, aRect)).Intersect(aRect);
 }
 
 FilterNodeTransformSoftware::FilterNodeTransformSoftware()
@@ -1069,25 +966,23 @@ FilterNodeTransformSoftware::InputIndex(
   }
 }
 
 void
 FilterNodeTransformSoftware::SetAttribute(uint32_t aIndex, uint32_t aFilter)
 {
   MOZ_ASSERT(aIndex == ATT_TRANSFORM_FILTER);
   mSamplingFilter = static_cast<SamplingFilter>(aFilter);
-  Invalidate();
 }
 
 void
 FilterNodeTransformSoftware::SetAttribute(uint32_t aIndex, const Matrix &aMatrix)
 {
   MOZ_ASSERT(aIndex == ATT_TRANSFORM_MATRIX);
   mMatrix = aMatrix;
-  Invalidate();
 }
 
 IntRect
 FilterNodeTransformSoftware::SourceRectForOutputRect(const IntRect &aRect)
 {
   if (aRect.IsEmpty()) {
     return IntRect();
   }
@@ -1152,22 +1047,16 @@ FilterNodeTransformSoftware::Render(cons
   dt->SetTransform(transform);
   dt->DrawSurface(input, r, r, DrawSurfaceOptions(mSamplingFilter));
 
   dt->Flush();
   surf->Unmap();
   return surf.forget();
 }
 
-void
-FilterNodeTransformSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_TRANSFORM_IN, SourceRectForOutputRect(aRect));
-}
-
 IntRect
 FilterNodeTransformSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   IntRect srcRect = SourceRectForOutputRect(aRect);
   if (srcRect.IsEmpty()) {
     return IntRect();
   }
 
@@ -1195,26 +1084,24 @@ FilterNodeMorphologySoftware::InputIndex
 
 void
 FilterNodeMorphologySoftware::SetAttribute(uint32_t aIndex,
                                            const IntSize &aRadii)
 {
   MOZ_ASSERT(aIndex == ATT_MORPHOLOGY_RADII);
   mRadii.width = std::min(std::max(aRadii.width, 0), 100000);
   mRadii.height = std::min(std::max(aRadii.height, 0), 100000);
-  Invalidate();
 }
 
 void
 FilterNodeMorphologySoftware::SetAttribute(uint32_t aIndex,
                                            uint32_t aOperator)
 {
   MOZ_ASSERT(aIndex == ATT_MORPHOLOGY_OPERATOR);
   mOperator = static_cast<MorphologyOperator>(aOperator);
-  Invalidate();
 }
 
 static already_AddRefed<DataSourceSurface>
 ApplyMorphology(const IntRect& aSourceRect, DataSourceSurface* aInput,
                 const IntRect& aDestRect, int32_t rx, int32_t ry,
                 MorphologyOperator aOperator)
 {
   IntRect srcRect = aSourceRect - aDestRect.TopLeft();
@@ -1293,24 +1180,16 @@ FilterNodeMorphologySoftware::Render(con
 
   if (rx == 0 && ry == 0) {
     return input.forget();
   }
 
   return ApplyMorphology(srcRect, input, aRect, rx, ry, mOperator);
 }
 
-void
-FilterNodeMorphologySoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  IntRect srcRect = aRect;
-  srcRect.Inflate(mRadii);
-  RequestInputRect(IN_MORPHOLOGY_IN, srcRect);
-}
-
 IntRect
 FilterNodeMorphologySoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   IntRect inflatedSourceRect = aRect;
   inflatedSourceRect.Inflate(mRadii);
   IntRect inputRect = GetInputRectInRect(IN_MORPHOLOGY_IN, inflatedSourceRect);
   if (mOperator == MORPHOLOGY_OPERATOR_ERODE) {
     inputRect.Deflate(mRadii);
@@ -1330,26 +1209,24 @@ FilterNodeColorMatrixSoftware::InputInde
 }
 
 void
 FilterNodeColorMatrixSoftware::SetAttribute(uint32_t aIndex,
                                             const Matrix5x4 &aMatrix)
 {
   MOZ_ASSERT(aIndex == ATT_COLOR_MATRIX_MATRIX);
   mMatrix = aMatrix;
-  Invalidate();
 }
 
 void
 FilterNodeColorMatrixSoftware::SetAttribute(uint32_t aIndex,
                                             uint32_t aAlphaMode)
 {
   MOZ_ASSERT(aIndex == ATT_COLOR_MATRIX_ALPHA_MODE);
   mAlphaMode = (AlphaMode)aAlphaMode;
-  Invalidate();
 }
 
 static already_AddRefed<DataSourceSurface>
 Premultiply(DataSourceSurface* aSurface)
 {
   if (aSurface->GetFormat() == SurfaceFormat::A8) {
     RefPtr<DataSourceSurface> surface(aSurface);
     return surface.forget();
@@ -1429,37 +1306,30 @@ FilterNodeColorMatrixSoftware::Render(co
 
   if (mAlphaMode == ALPHA_MODE_PREMULTIPLIED) {
     result = Premultiply(result);
   }
 
   return result.forget();
 }
 
-void
-FilterNodeColorMatrixSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_COLOR_MATRIX_IN, aRect);
-}
-
 IntRect
 FilterNodeColorMatrixSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   if (mMatrix._54 > 0.0f) {
     return aRect;
   }
   return GetInputRectInRect(IN_COLOR_MATRIX_IN, aRect);
 }
 
 void
 FilterNodeFloodSoftware::SetAttribute(uint32_t aIndex, const Color &aColor)
 {
   MOZ_ASSERT(aIndex == ATT_FLOOD_COLOR);
   mColor = aColor;
-  Invalidate();
 }
 
 static uint32_t
 ColorToBGRA(const Color& aColor)
 {
   union {
     uint32_t color;
     uint8_t components[4];
@@ -1552,17 +1422,16 @@ FilterNodeTileSoftware::InputIndex(uint3
 
 void
 FilterNodeTileSoftware::SetAttribute(uint32_t aIndex,
                                      const IntRect &aSourceRect)
 {
   MOZ_ASSERT(aIndex == ATT_TILE_SOURCE_RECT);
   mSourceRect = IntRect(int32_t(aSourceRect.x), int32_t(aSourceRect.y),
                         int32_t(aSourceRect.Width()), int32_t(aSourceRect.Height()));
-  Invalidate();
 }
 
 namespace {
 struct CompareIntRects
 {
   bool operator()(const IntRect& a, const IntRect& b) const
   {
     if (a.x != b.x) {
@@ -1641,25 +1510,16 @@ FilterNodeTileSoftware::Render(const Int
 
       CopyRect(input, target, srcRect - srcRect.TopLeft(), destRect.TopLeft() - aRect.TopLeft());
     }
   }
 
   return target.forget();
 }
 
-void
-FilterNodeTileSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  // Do not request anything.
-  // Source rects for the tile filter can be discontinuous with large gaps
-  // between them. Requesting those from our input filter might cause it to
-  // render the whole bounding box of all of them, which would be wasteful.
-}
-
 IntRect
 FilterNodeTileSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   return aRect;
 }
 
 FilterNodeComponentTransferSoftware::FilterNodeComponentTransferSoftware()
  : mDisableR(true)
@@ -1683,17 +1543,16 @@ FilterNodeComponentTransferSoftware::Set
       mDisableB = aDisable;
       break;
     case ATT_TRANSFER_DISABLE_A:
       mDisableA = aDisable;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeComponentTransferSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 void
 FilterNodeComponentTransferSoftware::GenerateLookupTable(ptrdiff_t aComponent,
                                                          uint8_t aTables[4][256],
                                                          bool aDisabled)
 {
   if (aDisabled) {
@@ -1810,22 +1669,16 @@ FilterNodeComponentTransferSoftware::Ren
     TransferComponents<1>(input, target, &lookupTables[B8G8R8A8_COMPONENT_BYTEOFFSET_A]);
   } else {
     TransferComponents<4>(input, target, lookupTables);
   }
 
   return target.forget();
 }
 
-void
-FilterNodeComponentTransferSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_TRANSFER_IN, aRect);
-}
-
 IntRect
 FilterNodeComponentTransferSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   if (mDisableA) {
     return GetInputRectInRect(IN_TRANSFER_IN, aRect);
   }
   return aRect;
 }
@@ -1856,17 +1709,16 @@ FilterNodeTableTransferSoftware::SetAttr
       mTableB = table;
       break;
     case ATT_TABLE_TRANSFER_TABLE_A:
       mTableA = table;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeTableTransferSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 void
 FilterNodeTableTransferSoftware::FillLookupTable(ptrdiff_t aComponent,
                                                  uint8_t aTable[256])
 {
   switch (aComponent) {
     case B8G8R8A8_COMPONENT_BYTEOFFSET_R:
@@ -1925,17 +1777,16 @@ FilterNodeDiscreteTransferSoftware::SetA
       mTableB = discrete;
       break;
     case ATT_DISCRETE_TRANSFER_TABLE_A:
       mTableA = discrete;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeDiscreteTransferSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 void
 FilterNodeDiscreteTransferSoftware::FillLookupTable(ptrdiff_t aComponent,
                                                     uint8_t aTable[256])
 {
   switch (aComponent) {
     case B8G8R8A8_COMPONENT_BYTEOFFSET_R:
@@ -2014,17 +1865,16 @@ FilterNodeLinearTransferSoftware::SetAtt
       mSlopeA = aValue;
       break;
     case ATT_LINEAR_TRANSFER_INTERCEPT_A:
       mInterceptA = aValue;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeLinearTransferSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 void
 FilterNodeLinearTransferSoftware::FillLookupTable(ptrdiff_t aComponent,
                                                   uint8_t aTable[256])
 {
   switch (aComponent) {
     case B8G8R8A8_COMPONENT_BYTEOFFSET_R:
@@ -2108,17 +1958,16 @@ FilterNodeGammaTransferSoftware::SetAttr
       mExponentA = aValue;
       break;
     case ATT_GAMMA_TRANSFER_OFFSET_A:
       mOffsetA = aValue;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeGammaTransferSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 void
 FilterNodeGammaTransferSoftware::FillLookupTable(ptrdiff_t aComponent,
                                                  uint8_t aTable[256])
 {
   switch (aComponent) {
     case B8G8R8A8_COMPONENT_BYTEOFFSET_R:
@@ -2170,92 +2019,84 @@ FilterNodeConvolveMatrixSoftware::InputI
 }
 
 void
 FilterNodeConvolveMatrixSoftware::SetAttribute(uint32_t aIndex,
                                                const IntSize &aKernelSize)
 {
   MOZ_ASSERT(aIndex == ATT_CONVOLVE_MATRIX_KERNEL_SIZE);
   mKernelSize = aKernelSize;
-  Invalidate();
 }
 
 void
 FilterNodeConvolveMatrixSoftware::SetAttribute(uint32_t aIndex,
                                                const Float *aMatrix,
                                                uint32_t aSize)
 {
   MOZ_ASSERT(aIndex == ATT_CONVOLVE_MATRIX_KERNEL_MATRIX);
   mKernelMatrix = std::vector<Float>(aMatrix, aMatrix + aSize);
-  Invalidate();
 }
 
 void
 FilterNodeConvolveMatrixSoftware::SetAttribute(uint32_t aIndex, Float aValue)
 {
   switch (aIndex) {
     case ATT_CONVOLVE_MATRIX_DIVISOR:
       mDivisor = aValue;
       break;
     case ATT_CONVOLVE_MATRIX_BIAS:
       mBias = aValue;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeConvolveMatrixSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 void
 FilterNodeConvolveMatrixSoftware::SetAttribute(uint32_t aIndex, const Size &aKernelUnitLength)
 {
   switch (aIndex) {
     case ATT_CONVOLVE_MATRIX_KERNEL_UNIT_LENGTH:
       mKernelUnitLength = aKernelUnitLength;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeConvolveMatrixSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 void
 FilterNodeConvolveMatrixSoftware::SetAttribute(uint32_t aIndex,
                                                const IntPoint &aTarget)
 {
   MOZ_ASSERT(aIndex == ATT_CONVOLVE_MATRIX_TARGET);
   mTarget = aTarget;
-  Invalidate();
 }
 
 void
 FilterNodeConvolveMatrixSoftware::SetAttribute(uint32_t aIndex,
                                                const IntRect &aSourceRect)
 {
   MOZ_ASSERT(aIndex == ATT_CONVOLVE_MATRIX_SOURCE_RECT);
   mSourceRect = aSourceRect;
-  Invalidate();
 }
 
 void
 FilterNodeConvolveMatrixSoftware::SetAttribute(uint32_t aIndex,
                                                uint32_t aEdgeMode)
 {
   MOZ_ASSERT(aIndex == ATT_CONVOLVE_MATRIX_EDGE_MODE);
   mEdgeMode = static_cast<ConvolveMatrixEdgeMode>(aEdgeMode);
-  Invalidate();
 }
 
 void
 FilterNodeConvolveMatrixSoftware::SetAttribute(uint32_t aIndex,
                                                bool aPreserveAlpha)
 {
   MOZ_ASSERT(aIndex == ATT_CONVOLVE_MATRIX_PRESERVE_ALPHA);
   mPreserveAlpha = aPreserveAlpha;
-  Invalidate();
 }
 
 #ifdef DEBUG
 static bool sColorSamplingAccessControlEnabled = false;
 static uint8_t* sColorSamplingAccessControlStart = nullptr;
 static uint8_t* sColorSamplingAccessControlEnd = nullptr;
 
 struct DebugOnlyAutoColorSamplingAccessControl
@@ -2514,22 +2355,16 @@ FilterNodeConvolveMatrixSoftware::DoRend
                     aKernelUnitLengthX, aKernelUnitLengthY);
     }
   }
   delete[] intKernel;
 
   return target.forget();
 }
 
-void
-FilterNodeConvolveMatrixSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_CONVOLVE_MATRIX_IN, InflatedSourceRect(aRect));
-}
-
 IntRect
 FilterNodeConvolveMatrixSoftware::InflatedSourceRect(const IntRect &aDestRect)
 {
   if (aDestRect.IsEmpty()) {
     return IntRect();
   }
 
   IntMargin margin;
@@ -2586,33 +2421,31 @@ FilterNodeDisplacementMapSoftware::Input
 }
 
 void
 FilterNodeDisplacementMapSoftware::SetAttribute(uint32_t aIndex,
                                                 Float aScale)
 {
   MOZ_ASSERT(aIndex == ATT_DISPLACEMENT_MAP_SCALE);
   mScale = aScale;
-  Invalidate();
 }
 
 void
 FilterNodeDisplacementMapSoftware::SetAttribute(uint32_t aIndex, uint32_t aValue)
 {
   switch (aIndex) {
     case ATT_DISPLACEMENT_MAP_X_CHANNEL:
       mChannelX = static_cast<ColorChannel>(aValue);
       break;
     case ATT_DISPLACEMENT_MAP_Y_CHANNEL:
       mChannelY = static_cast<ColorChannel>(aValue);
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeDisplacementMapSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 already_AddRefed<DataSourceSurface>
 FilterNodeDisplacementMapSoftware::Render(const IntRect& aRect)
 {
   IntRect srcRect = InflatedSourceOrDestRect(aRect);
   RefPtr<DataSourceSurface> input =
     GetInputDataSourceSurface(IN_DISPLACEMENT_MAP_IN, srcRect, NEED_COLOR_CHANNELS);
@@ -2665,23 +2498,16 @@ FilterNodeDisplacementMapSoftware::Rende
 
     // Keep valgrind happy.
     PodZero(&targetData[y * targetStride + 4 * aRect.Width()], targetStride - 4 * aRect.Width());
   }
 
   return target.forget();
 }
 
-void
-FilterNodeDisplacementMapSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_DISPLACEMENT_MAP_IN, InflatedSourceOrDestRect(aRect));
-  RequestInputRect(IN_DISPLACEMENT_MAP_IN2, aRect);
-}
-
 IntRect
 FilterNodeDisplacementMapSoftware::InflatedSourceOrDestRect(const IntRect &aDestOrSourceRect)
 {
   IntRect sourceOrDestRect = aDestOrSourceRect;
   sourceOrDestRect.Inflate(ceil(fabs(mScale) / 2));
   return sourceOrDestRect;
 }
 
@@ -2712,39 +2538,36 @@ FilterNodeTurbulenceSoftware::SetAttribu
   switch (aIndex) {
     case ATT_TURBULENCE_BASE_FREQUENCY:
       mBaseFrequency = aBaseFrequency;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeTurbulenceSoftware::SetAttribute");
       break;
   }
-  Invalidate();
 }
 
 void
 FilterNodeTurbulenceSoftware::SetAttribute(uint32_t aIndex, const IntRect &aRect)
 {
   switch (aIndex) {
     case ATT_TURBULENCE_RECT:
       mRenderRect = aRect;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeTurbulenceSoftware::SetAttribute");
       break;
   }
-  Invalidate();
 }
 
 void
 FilterNodeTurbulenceSoftware::SetAttribute(uint32_t aIndex, bool aStitchable)
 {
   MOZ_ASSERT(aIndex == ATT_TURBULENCE_STITCHABLE);
   mStitchable = aStitchable;
-  Invalidate();
 }
 
 void
 FilterNodeTurbulenceSoftware::SetAttribute(uint32_t aIndex, uint32_t aValue)
 {
   switch (aIndex) {
     case ATT_TURBULENCE_NUM_OCTAVES:
       mNumOctaves = aValue;
@@ -2754,17 +2577,16 @@ FilterNodeTurbulenceSoftware::SetAttribu
       break;
     case ATT_TURBULENCE_TYPE:
       mType = static_cast<TurbulenceType>(aValue);
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeTurbulenceSoftware::SetAttribute");
       break;
   }
-  Invalidate();
 }
 
 already_AddRefed<DataSourceSurface>
 FilterNodeTurbulenceSoftware::Render(const IntRect& aRect)
 {
   return FilterProcessing::RenderTurbulence(
     aRect.Size(), aRect.TopLeft(), mBaseFrequency,
     mSeed, mNumOctaves, mType, mStitchable, Rect(mRenderRect));
@@ -2798,18 +2620,16 @@ FilterNodeArithmeticCombineSoftware::Set
 {
   MOZ_ASSERT(aIndex == ATT_ARITHMETIC_COMBINE_COEFFICIENTS);
   MOZ_ASSERT(aSize == 4);
 
   mK1 = aFloat[0];
   mK2 = aFloat[1];
   mK3 = aFloat[2];
   mK4 = aFloat[3];
-
-  Invalidate();
 }
 
 already_AddRefed<DataSourceSurface>
 FilterNodeArithmeticCombineSoftware::Render(const IntRect& aRect)
 {
   RefPtr<DataSourceSurface> input1 =
     GetInputDataSourceSurface(IN_ARITHMETIC_COMBINE_IN, aRect, NEED_COLOR_CHANNELS);
   RefPtr<DataSourceSurface> input2 =
@@ -2830,23 +2650,16 @@ FilterNodeArithmeticCombineSoftware::Ren
     k1 = 0.0f;
     k3 = 0.0f;
     input2 = input1;
   }
 
   return FilterProcessing::ApplyArithmeticCombine(input1, input2, k1, k2, k3, k4);
 }
 
-void
-FilterNodeArithmeticCombineSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_ARITHMETIC_COMBINE_IN, aRect);
-  RequestInputRect(IN_ARITHMETIC_COMBINE_IN2, aRect);
-}
-
 IntRect
 FilterNodeArithmeticCombineSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   if (mK4 > 0.0f) {
     return aRect;
   }
   IntRect rectFrom1 = GetInputRectInRect(IN_ARITHMETIC_COMBINE_IN, aRect).Intersect(aRect);
   IntRect rectFrom2 = GetInputRectInRect(IN_ARITHMETIC_COMBINE_IN2, aRect).Intersect(aRect);
@@ -2873,17 +2686,16 @@ FilterNodeCompositeSoftware::InputIndex(
   return aInputEnumIndex - IN_COMPOSITE_IN_START;
 }
 
 void
 FilterNodeCompositeSoftware::SetAttribute(uint32_t aIndex, uint32_t aCompositeOperator)
 {
   MOZ_ASSERT(aIndex == ATT_COMPOSITE_OPERATOR);
   mOperator = static_cast<CompositeOperator>(aCompositeOperator);
-  Invalidate();
 }
 
 already_AddRefed<DataSourceSurface>
 FilterNodeCompositeSoftware::Render(const IntRect& aRect)
 {
   RefPtr<DataSourceSurface> start =
     GetInputDataSourceSurface(IN_COMPOSITE_IN_START, aRect, NEED_COLOR_CHANNELS);
   RefPtr<DataSourceSurface> dest =
@@ -2920,24 +2732,16 @@ FilterNodeCompositeSoftware::Render(cons
           // no additional input can get rid of that transparency.
           return nullptr;
       }
     }
   }
   return dest.forget();
 }
 
-void
-FilterNodeCompositeSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  for (size_t inputIndex = 0; inputIndex < NumberOfSetInputs(); inputIndex++) {
-    RequestInputRect(IN_COMPOSITE_IN_START + inputIndex, aRect);
-  }
-}
-
 IntRect
 FilterNodeCompositeSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   IntRect rect;
   for (size_t inputIndex = 0; inputIndex < NumberOfSetInputs(); inputIndex++) {
     IntRect inputRect = GetInputRectInRect(IN_COMPOSITE_IN_START + inputIndex, aRect);
     if (mOperator == COMPOSITE_OPERATOR_IN && inputIndex > 0) {
       rect = rect.Intersect(inputRect);
@@ -3013,22 +2817,16 @@ FilterNodeBlurXYSoftware::Render(const I
       blur.Blur(channel3Map.GetData());
     }
     target = FilterProcessing::CombineColorChannels(channel0, channel1, channel2, channel3);
   }
 
   return GetDataSurfaceInRect(target, srcRect, aRect, EDGE_MODE_NONE);
 }
 
-void
-FilterNodeBlurXYSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_GAUSSIAN_BLUR_IN, InflatedSourceOrDestRect(aRect));
-}
-
 IntRect
 FilterNodeBlurXYSoftware::InflatedSourceOrDestRect(const IntRect &aDestRect)
 {
   Size sigmaXY = StdDeviationXY();
   IntSize d = AlphaBoxBlur::CalculateBlurRadius(Point(sigmaXY.width, sigmaXY.height));
   IntRect srcRect = aDestRect;
   srcRect.Inflate(d);
   return srcRect;
@@ -3059,17 +2857,16 @@ FilterNodeGaussianBlurSoftware::SetAttri
 {
   switch (aIndex) {
     case ATT_GAUSSIAN_BLUR_STD_DEVIATION:
       mStdDeviation = ClampStdDeviation(aStdDeviation);
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeGaussianBlurSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 Size
 FilterNodeGaussianBlurSoftware::StdDeviationXY()
 {
   return Size(mStdDeviation, mStdDeviation);
 }
 
@@ -3083,31 +2880,29 @@ FilterNodeDirectionalBlurSoftware::SetAt
 {
   switch (aIndex) {
     case ATT_DIRECTIONAL_BLUR_STD_DEVIATION:
       mStdDeviation = ClampStdDeviation(aStdDeviation);
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeDirectionalBlurSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 void
 FilterNodeDirectionalBlurSoftware::SetAttribute(uint32_t aIndex,
                                                 uint32_t aBlurDirection)
 {
   switch (aIndex) {
     case ATT_DIRECTIONAL_BLUR_DIRECTION:
       mBlurDirection = (BlurDirection)aBlurDirection;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeDirectionalBlurSoftware::SetAttribute");
   }
-  Invalidate();
 }
 
 Size
 FilterNodeDirectionalBlurSoftware::StdDeviationXY()
 {
   float sigmaX = mBlurDirection == BLUR_DIRECTION_X ? mStdDeviation : 0;
   float sigmaY = mBlurDirection == BLUR_DIRECTION_Y ? mStdDeviation : 0;
   return Size(sigmaX, sigmaY);
@@ -3127,31 +2922,24 @@ FilterNodeCropSoftware::SetAttribute(uin
                                      const Rect &aSourceRect)
 {
   MOZ_ASSERT(aIndex == ATT_CROP_RECT);
   Rect srcRect = aSourceRect;
   srcRect.Round();
   if (!srcRect.ToIntRect(&mCropRect)) {
     mCropRect = IntRect();
   }
-  Invalidate();
 }
 
 already_AddRefed<DataSourceSurface>
 FilterNodeCropSoftware::Render(const IntRect& aRect)
 {
   return GetInputDataSourceSurface(IN_CROP_IN, aRect.Intersect(mCropRect));
 }
 
-void
-FilterNodeCropSoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_CROP_IN, aRect.Intersect(mCropRect));
-}
-
 IntRect
 FilterNodeCropSoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   return GetInputRectInRect(IN_CROP_IN, aRect).Intersect(mCropRect);
 }
 
 int32_t
 FilterNodePremultiplySoftware::InputIndex(uint32_t aInputEnumIndex)
@@ -3165,22 +2953,16 @@ FilterNodePremultiplySoftware::InputInde
 already_AddRefed<DataSourceSurface>
 FilterNodePremultiplySoftware::Render(const IntRect& aRect)
 {
   RefPtr<DataSourceSurface> input =
     GetInputDataSourceSurface(IN_PREMULTIPLY_IN, aRect);
   return input ? Premultiply(input) : nullptr;
 }
 
-void
-FilterNodePremultiplySoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_PREMULTIPLY_IN, aRect);
-}
-
 IntRect
 FilterNodePremultiplySoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   return GetInputRectInRect(IN_PREMULTIPLY_IN, aRect);
 }
 
 int32_t
 FilterNodeUnpremultiplySoftware::InputIndex(uint32_t aInputEnumIndex)
@@ -3194,22 +2976,16 @@ FilterNodeUnpremultiplySoftware::InputIn
 already_AddRefed<DataSourceSurface>
 FilterNodeUnpremultiplySoftware::Render(const IntRect& aRect)
 {
   RefPtr<DataSourceSurface> input =
     GetInputDataSourceSurface(IN_UNPREMULTIPLY_IN, aRect);
   return input ? Unpremultiply(input) : nullptr;
 }
 
-void
-FilterNodeUnpremultiplySoftware::RequestFromInputsForRect(const IntRect &aRect)
-{
-  RequestInputRect(IN_UNPREMULTIPLY_IN, aRect);
-}
-
 IntRect
 FilterNodeUnpremultiplySoftware::GetOutputRectInRect(const IntRect& aRect)
 {
   return GetInputRectInRect(IN_UNPREMULTIPLY_IN, aRect);
 }
 
 bool
 PointLightSoftware::SetAttribute(uint32_t aIndex, const Point3D &aPoint)
@@ -3310,62 +3086,57 @@ FilterNodeLightingSoftware<LightType, Li
   }
 }
 
 template<typename LightType, typename LightingType>
 void
 FilterNodeLightingSoftware<LightType, LightingType>::SetAttribute(uint32_t aIndex, const Point3D &aPoint)
 {
   if (mLight.SetAttribute(aIndex, aPoint)) {
-    Invalidate();
     return;
   }
   MOZ_CRASH("GFX: FilterNodeLightingSoftware::SetAttribute point");
 }
 
 template<typename LightType, typename LightingType>
 void
 FilterNodeLightingSoftware<LightType, LightingType>::SetAttribute(uint32_t aIndex, Float aValue)
 {
   if (mLight.SetAttribute(aIndex, aValue) ||
       mLighting.SetAttribute(aIndex, aValue)) {
-    Invalidate();
     return;
   }
   switch (aIndex) {
     case ATT_LIGHTING_SURFACE_SCALE:
       mSurfaceScale = std::fpclassify(aValue) == FP_SUBNORMAL ? 0.0 : aValue;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeLightingSoftware::SetAttribute float");
   }
-  Invalidate();
 }
 
 template<typename LightType, typename LightingType>
 void
 FilterNodeLightingSoftware<LightType, LightingType>::SetAttribute(uint32_t aIndex, const Size &aKernelUnitLength)
 {
   switch (aIndex) {
     case ATT_LIGHTING_KERNEL_UNIT_LENGTH:
       mKernelUnitLength = aKernelUnitLength;
       break;
     default:
       MOZ_CRASH("GFX: FilterNodeLightingSoftware::SetAttribute size");
   }
-  Invalidate();
 }
 
 template<typename LightType, typename LightingType>
 void
 FilterNodeLightingSoftware<LightType, LightingType>::SetAttribute(uint32_t aIndex, const Color &aColor)
 {
   MOZ_ASSERT(aIndex == ATT_LIGHTING_COLOR);
   mColor = aColor;
-  Invalidate();
 }
 
 template<typename LightType, typename LightingType>
 IntRect
 FilterNodeLightingSoftware<LightType, LightingType>::GetOutputRectInRect(const IntRect& aRect)
 {
   return aRect;
 }
@@ -3486,26 +3257,16 @@ FilterNodeLightingSoftware<LightType, Li
 {
   if (mKernelUnitLength.width == floor(mKernelUnitLength.width) &&
       mKernelUnitLength.height == floor(mKernelUnitLength.height)) {
     return DoRender(aRect, (int32_t)mKernelUnitLength.width, (int32_t)mKernelUnitLength.height);
   }
   return DoRender(aRect, mKernelUnitLength.width, mKernelUnitLength.height);
 }
 
-template<typename LightType, typename LightingType>
-void
-FilterNodeLightingSoftware<LightType, LightingType>::RequestFromInputsForRect(const IntRect &aRect)
-{
-  IntRect srcRect = aRect;
-  srcRect.Inflate(ceil(mKernelUnitLength.width),
-                  ceil(mKernelUnitLength.height));
-  RequestInputRect(IN_LIGHTING_IN, srcRect);
-}
-
 template<typename LightType, typename LightingType> template<typename CoordType>
 already_AddRefed<DataSourceSurface>
 FilterNodeLightingSoftware<LightType, LightingType>::DoRender(const IntRect& aRect,
                                                               CoordType aKernelUnitLengthX,
                                                               CoordType aKernelUnitLengthY)
 {
   MOZ_ASSERT(aKernelUnitLengthX > 0, "aKernelUnitLengthX can be a negative or zero value");
   MOZ_ASSERT(aKernelUnitLengthY > 0, "aKernelUnitLengthY can be a negative or zero value");
--- a/gfx/2d/FilterNodeSoftware.h
+++ b/gfx/2d/FilterNodeSoftware.h
@@ -15,34 +15,21 @@ namespace mozilla {
 namespace gfx {
 
 class DataSourceSurface;
 class DrawTarget;
 struct DrawOptions;
 class FilterNodeSoftware;
 
 /**
- * Can be attached to FilterNodeSoftware instances using
- * AddInvalidationListener. FilterInvalidated is called whenever the output of
- * the observed filter may have changed; that is, whenever cached GetOutput()
- * results (and results derived from them) need to discarded.
- */
-class FilterInvalidationListener
-{
-public:
-  virtual void FilterInvalidated(FilterNodeSoftware* aFilter) = 0;
-};
-
-/**
  * This is the base class for the software (i.e. pure CPU, non-accelerated)
  * FilterNode implementation. The software implementation is backend-agnostic,
  * so it can be used as a fallback for all DrawTarget implementations.
  */
-class FilterNodeSoftware : public FilterNode,
-                           public FilterInvalidationListener
+class FilterNodeSoftware : public FilterNode
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeSoftware, override)
   virtual ~FilterNodeSoftware();
 
   // Factory method, intended to be called from DrawTarget*::CreateFilter.
   static already_AddRefed<FilterNode> Create(FilterType aType);
 
@@ -51,22 +38,16 @@ public:
             const Point &aDestPoint, const DrawOptions &aOptions);
 
   virtual FilterBackend GetBackendType() override { return FILTER_BACKEND_SOFTWARE; }
   virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) override;
   virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) override;
 
   virtual const char* GetName() { return "Unknown"; }
 
-  virtual void AddInvalidationListener(FilterInvalidationListener* aListener);
-  virtual void RemoveInvalidationListener(FilterInvalidationListener* aListener);
-
-  // FilterInvalidationListener implementation
-  virtual void FilterInvalidated(FilterNodeSoftware* aFilter) override;
-
 protected:
 
   // The following methods are intended to be overriden by subclasses.
 
   /**
    * Translates a *FilterInputs enum value into an index for the
    * mInputFilters / mInputSurfaces arrays. Returns -1 for invalid inputs.
    * If somebody calls SetInput(enumValue, input) with an enumValue for which
@@ -90,23 +71,16 @@ protected:
    * May return nullptr in error conditions or for an empty aRect.
    * Implementations are not required to allocate a new surface and may even
    * pass through input surfaces unchanged.
    * Callers need to treat the returned surface as immutable.
    */
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) = 0;
 
   /**
-   * Call RequestRect (see below) on any input filters with the desired input
-   * rect, so that the input filter knows what to cache the next time it
-   * renders.
-   */
-  virtual void RequestFromInputsForRect(const IntRect &aRect) {}
-
-  /**
    * This method provides a caching default implementation but can be overriden
    * by subclasses that don't want to cache their output. Those classes should
    * call Render(aRect) directly from here.
    */
   virtual already_AddRefed<DataSourceSurface> GetOutput(const IntRect &aRect);
 
   // The following methods are non-virtual helper methods.
 
@@ -149,75 +123,36 @@ protected:
 
   /**
    * Returns the intersection of the input filter's or surface's output rect
    * with aInRect.
    */
   IntRect GetInputRectInRect(uint32_t aInputEnumIndex, const IntRect& aInRect);
 
   /**
-   * Calls RequestRect on the specified input, if it's a filter.
-   */
-  void RequestInputRect(uint32_t aInputEnumIndex, const IntRect& aRect);
-
-  /**
    * Returns the number of set input filters or surfaces. Needed for filters
    * which can have an arbitrary number of inputs.
    */
   size_t NumberOfSetInputs();
 
   /**
-   * Discard the cached surface that was stored in the GetOutput default
-   * implementation. Needs to be called whenever attributes or inputs are set
-   * that might change the result of a Render() call.
-   */
-  void Invalidate();
-
-  /**
-   * Called in order to let this filter know what to cache during the next
-   * GetOutput call. Expected to call RequestRect on this filter's input
-   * filters.
-   */
-  void RequestRect(const IntRect &aRect);
-
-  /**
    * Set input filter and clear input surface for this input index, or set
    * input surface and clear input filter. One of aSurface and aFilter should
    * be null.
    */
   void SetInput(uint32_t aIndex, SourceSurface *aSurface,
                 FilterNodeSoftware *aFilter);
 
 protected:
   /**
    * mInputSurfaces / mInputFilters: For each input index, either a surface or
    * a filter is set, and the other is null.
    */
   std::vector<RefPtr<SourceSurface> > mInputSurfaces;
   std::vector<RefPtr<FilterNodeSoftware> > mInputFilters;
-
-  /**
-   * Weak pointers to our invalidation listeners, i.e. to those filters who
-   * have this filter as an input. Invalidation listeners are required to
-   * unsubscribe themselves from us when they let go of their reference to us.
-   * This ensures that the pointers in this array are never stale.
-   */
-  std::vector<FilterInvalidationListener*> mInvalidationListeners;
-
-  /**
-   * Stores the rect which we want to render and cache on the next call to
-   * GetOutput.
-   */
-  IntRect mRequestedRect;
-
-  /**
-   * Stores our cached output.
-   */
-  IntRect mCachedRect;
-  RefPtr<DataSourceSurface> mCachedOutput;
 };
 
 // Subclasses for specific filters.
 
 class FilterNodeTransformSoftware : public FilterNodeSoftware
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTransformSoftware, override)
@@ -226,17 +161,16 @@ public:
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aGraphicsFilter) override;
   virtual void SetAttribute(uint32_t aIndex, const Matrix &aMatrix) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
   IntRect SourceRectForOutputRect(const IntRect &aRect);
 
 private:
   Matrix mMatrix;
   SamplingFilter mSamplingFilter;
 };
 
 class FilterNodeBlendSoftware : public FilterNodeSoftware
@@ -247,17 +181,16 @@ public:
   virtual const char* GetName() override { return "Blend"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aBlendMode) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   BlendMode mBlendMode;
 };
 
 class FilterNodeMorphologySoftware : public FilterNodeSoftware
 {
 public:
@@ -267,17 +200,16 @@ public:
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntSize &aRadii) override;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   IntSize mRadii;
   MorphologyOperator mOperator;
 };
 
 class FilterNodeColorMatrixSoftware : public FilterNodeSoftware
 {
@@ -287,17 +219,16 @@ public:
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Matrix5x4 &aMatrix) override;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aAlphaMode) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   Matrix5x4 mMatrix;
   AlphaMode mAlphaMode;
 };
 
 class FilterNodeFloodSoftware : public FilterNodeSoftware
 {
@@ -323,17 +254,16 @@ public:
   virtual const char* GetName() override { return "Tile"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aSourceRect) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   IntRect mSourceRect;
 };
 
 /**
  * Baseclass for the four different component transfer filters.
  */
@@ -345,17 +275,16 @@ public:
 
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, bool aDisable) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
   virtual void GenerateLookupTable(ptrdiff_t aComponent, uint8_t aTables[4][256],
                                    bool aDisabled);
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) = 0;
 
   bool mDisableR;
   bool mDisableG;
   bool mDisableB;
   bool mDisableA;
@@ -470,17 +399,16 @@ public:
   virtual void SetAttribute(uint32_t aIndex, const IntPoint &aTarget) override;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aEdgeMode) override;
   virtual void SetAttribute(uint32_t aIndex, bool aPreserveAlpha) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   template<typename CoordType>
   already_AddRefed<DataSourceSurface> DoRender(const IntRect& aRect,
                                            CoordType aKernelUnitLengthX,
                                            CoordType aKernelUnitLengthY);
 
   IntRect InflatedSourceRect(const IntRect &aDestRect);
@@ -506,17 +434,16 @@ public:
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aScale) override;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aValue) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   IntRect InflatedSourceOrDestRect(const IntRect &aDestOrSourceRect);
 
   Float mScale;
   ColorChannel mChannelX;
   ColorChannel mChannelY;
 };
@@ -555,17 +482,16 @@ public:
   virtual const char* GetName() override { return "ArithmeticCombine"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   Float mK1;
   Float mK2;
   Float mK3;
   Float mK4;
 };
 
@@ -577,34 +503,32 @@ public:
   virtual const char* GetName() override { return "Composite"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   CompositeOperator mOperator;
 };
 
 // Base class for FilterNodeGaussianBlurSoftware and
 // FilterNodeDirectionalBlurSoftware.
 class FilterNodeBlurXYSoftware : public FilterNodeSoftware
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeBlurXYSoftware, override)
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
   IntRect InflatedSourceOrDestRect(const IntRect &aDestRect);
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
   // Implemented by subclasses.
   virtual Size StdDeviationXY() = 0;
 };
 
 class FilterNodeGaussianBlurSoftware : public FilterNodeBlurXYSoftware
 {
 public:
@@ -646,44 +570,41 @@ public:
   virtual const char* GetName() override { return "Crop"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Rect &aSourceRect) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   IntRect mCropRect;
 };
 
 class FilterNodePremultiplySoftware : public FilterNodeSoftware
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodePremultiplySoftware, override)
   virtual const char* GetName() override { return "Premultiply"; }
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 };
 
 class FilterNodeUnpremultiplySoftware : public FilterNodeSoftware
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeUnpremultiplySoftware, override)
   virtual const char* GetName() override { return "Unpremultiply"; }
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 };
 
 template<typename LightType, typename LightingType>
 class FilterNodeLightingSoftware : public FilterNodeSoftware
 {
 public:
 #if defined(MOZILLA_INTERNAL_API) && (defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING))
   // Helpers for refcounted
@@ -697,17 +618,16 @@ public:
   virtual void SetAttribute(uint32_t aIndex, const Size &) override;
   virtual void SetAttribute(uint32_t aIndex, const Point3D &) override;
   virtual void SetAttribute(uint32_t aIndex, const Color &) override;
 
 protected:
   virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
-  virtual void RequestFromInputsForRect(const IntRect &aRect) override;
 
 private:
   template<typename CoordType>
   already_AddRefed<DataSourceSurface> DoRender(const IntRect& aRect,
                                            CoordType aKernelUnitLengthX,
                                            CoordType aKernelUnitLengthY);
 
   Mutex mLock;