Bug 1260611 - Part 3: Hold on to TextureHosts until the following composite is done. r=sotaro a=ritu
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 11 May 2016 10:55:17 +1200
changeset 333026 33693d8bdec17f07fc460ca7cc908ade88f97b86
parent 333025 0ecc04efa7429aa767539a40c9bf2cdea2380d45
child 333027 e6b03d71815222297fdf701695ddd2cc743b0a80
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro, ritu
bugs1260611
milestone48.0a2
Bug 1260611 - Part 3: Hold on to TextureHosts until the following composite is done. r=sotaro a=ritu
gfx/layers/composite/ImageHost.cpp
gfx/layers/composite/LayerManagerComposite.cpp
gfx/layers/composite/LayerManagerComposite.h
--- a/gfx/layers/composite/ImageHost.cpp
+++ b/gfx/layers/composite/ImageHost.cpp
@@ -326,16 +326,21 @@ ImageHost::Composite(LayerComposite* aLa
   }
 
   if (uint32_t(imageIndex) + 1 < mImages.Length()) {
     GetCompositor()->CompositeUntil(mImages[imageIndex + 1].mTimeStamp + TimeDuration::FromMilliseconds(BIAS_TIME_MS));
   }
 
   TimedImage* img = &mImages[imageIndex];
   img->mTextureHost->SetCompositor(GetCompositor());
+  // If this TextureHost will be recycled, then make sure we hold a reference to
+  // it until we're sure that the compositor has finished reading from it.
+  if (img->mTextureHost->GetFlags() & TextureFlags::RECYCLE) {
+    aLayer->GetLayerManager()->HoldTextureUntilNextComposite(img->mTextureHost);
+  }
   SetCurrentTextureHost(img->mTextureHost);
 
   {
     AutoLockCompositableHost autoLock(this);
     if (autoLock.Failed()) {
       NS_WARNING("failed to lock front buffer");
       return;
     }
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -387,16 +387,19 @@ LayerManagerComposite::EndTransaction(co
   // Set composition timestamp here because we need it in
   // ComputeEffectiveTransforms (so the correct video frame size is picked) and
   // also to compute invalid regions properly.
   mCompositor->SetCompositionTime(aTimeStamp);
 
   if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
     MOZ_ASSERT(!aTimeStamp.IsNull());
     UpdateAndRender();
+
+    mPreviousHeldTextureHosts.Clear();
+    mPreviousHeldTextureHosts.SwapElements(mCurrentHeldTextureHosts);
   } else {
     // Modified the layer tree.
     mGeometryChanged = true;
   }
 
   mCompositor->ClearTargetContext();
   mTarget = nullptr;
 
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -332,16 +332,20 @@ public:
 
   // Indicate that we need to composite even if nothing in our layers has
   // changed, so that the widget can draw something different in its window
   // overlay.
   void SetWindowOverlayChanged() { mWindowOverlayChanged = true; }
 
   void ForcePresent() { mCompositor->ForcePresent(); }
 
+  void HoldTextureUntilNextComposite(TextureHost* aTextureHost) {
+    mCurrentHeldTextureHosts.AppendElement(aTextureHost);
+  }
+
 private:
   /** Region we're clipping our current drawing to. */
   nsIntRegion mClippingRegion;
   gfx::IntRect mRenderBounds;
 
   /** Current root layer. */
   LayerComposite* RootLayer() const;
 
@@ -392,16 +396,19 @@ private:
   float mWarningLevel;
   mozilla::TimeStamp mWarnTime;
   bool mUnusedApzTransformWarning;
   RefPtr<Compositor> mCompositor;
   UniquePtr<LayerProperties> mClonedLayerTreeProperties;
 
   nsTArray<ImageCompositeNotification> mImageCompositeNotifications;
 
+  nsTArray<RefPtr<TextureHost>> mCurrentHeldTextureHosts;
+  nsTArray<RefPtr<TextureHost>> mPreviousHeldTextureHosts;
+
   /**
    * Context target, nullptr when drawing directly to our swap chain.
    */
   RefPtr<gfx::DrawTarget> mTarget;
   gfx::IntRect mTargetBounds;
 
   nsIntRegion mInvalidRegion;