Bug 1462903 - Always send a display list for a new async image pipeline so WR doesn't complain. r?sotaro draft
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 24 May 2018 09:59:28 -0400
changeset 799440 53cd3281f0517b6a6ad194d9686abb267a4e4413
parent 799267 043e4ab6e72469ed8121f4da98dcdfef983a49d9
push id111050
push userkgupta@mozilla.com
push dateThu, 24 May 2018 16:53:01 +0000
reviewerssotaro
bugs1462903
milestone62.0a1
Bug 1462903 - Always send a display list for a new async image pipeline so WR doesn't complain. r?sotaro MozReview-Commit-ID: IXM8EhkcdjE
gfx/layers/wr/AsyncImagePipelineManager.cpp
gfx/layers/wr/AsyncImagePipelineManager.h
--- a/gfx/layers/wr/AsyncImagePipelineManager.cpp
+++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp
@@ -16,16 +16,17 @@
 #include "mozilla/webrender/WebRenderAPI.h"
 #include "mozilla/webrender/WebRenderTypes.h"
 
 namespace mozilla {
 namespace layers {
 
 AsyncImagePipelineManager::AsyncImagePipeline::AsyncImagePipeline()
  : mInitialised(false)
+ , mSentDL(false)
  , mIsChanged(false)
  , mUseExternalImage(false)
  , mFilter(wr::ImageRendering::Auto)
  , mMixBlendMode(wr::MixBlendMode::Normal)
 {}
 
 AsyncImagePipelineManager::AsyncImagePipelineManager(already_AddRefed<wr::WebRenderAPI>&& aApi)
  : mApi(aApi)
@@ -282,75 +283,84 @@ AsyncImagePipelineManager::ApplyAsyncIma
 
     nsTArray<wr::ImageKey> keys;
     auto op = UpdateImageKeys(aTxn, pipeline, keys);
 
     bool updateDisplayList = pipeline->mInitialised &&
                              (pipeline->mIsChanged || op == Some(TextureHost::ADD_IMAGE)) &&
                              !!pipeline->mCurrentTexture;
 
+    if (!pipeline->mSentDL) {
+      // If we haven't sent a display list yet, do it anyway, even if it's just
+      // an empty DL with a stacking context and no actual image. Otherwise WR
+      // will assert about missing the pipeline
+      updateDisplayList = true;
+    }
+
     // Request to generate frame if there is an update.
     if (updateDisplayList || !op.isNothing()) {
       SetWillGenerateFrame();
     }
 
     if (!updateDisplayList) {
       // We don't need to update the display list, either because we can't or because
       // the previous one is still up to date.
       // We may, however, have updated some resources.
       aTxn.UpdateEpoch(pipelineId, epoch);
       if (pipeline->mCurrentTexture) {
         HoldExternalImage(pipelineId, epoch, pipeline->mCurrentTexture->AsWebRenderTextureHost());
       }
       continue;
     }
+
+    pipeline->mSentDL = true;
     pipeline->mIsChanged = false;
 
     wr::LayoutSize contentSize { pipeline->mScBounds.Width(), pipeline->mScBounds.Height() };
     wr::DisplayListBuilder builder(pipelineId, contentSize);
 
-    MOZ_ASSERT(!keys.IsEmpty());
-    MOZ_ASSERT(pipeline->mCurrentTexture.get());
-
     float opacity = 1.0f;
     builder.PushStackingContext(wr::ToLayoutRect(pipeline->mScBounds),
                                 nullptr,
                                 nullptr,
                                 &opacity,
                                 pipeline->mScTransform.IsIdentity() ? nullptr : &pipeline->mScTransform,
                                 wr::TransformStyle::Flat,
                                 nullptr,
                                 pipeline->mMixBlendMode,
                                 nsTArray<wr::WrFilterOp>(),
                                 true,
                                 // This is fine to do unconditionally because we only push images here.
                                 wr::GlyphRasterSpace::Screen());
 
-    LayoutDeviceRect rect(0, 0, pipeline->mCurrentTexture->GetSize().width, pipeline->mCurrentTexture->GetSize().height);
-    if (pipeline->mScaleToSize.isSome()) {
-      rect = LayoutDeviceRect(0, 0, pipeline->mScaleToSize.value().width, pipeline->mScaleToSize.value().height);
+    if (pipeline->mCurrentTexture && !keys.IsEmpty()) {
+      LayoutDeviceRect rect(0, 0, pipeline->mCurrentTexture->GetSize().width, pipeline->mCurrentTexture->GetSize().height);
+      if (pipeline->mScaleToSize.isSome()) {
+        rect = LayoutDeviceRect(0, 0, pipeline->mScaleToSize.value().width, pipeline->mScaleToSize.value().height);
+      }
+
+      if (pipeline->mUseExternalImage) {
+        MOZ_ASSERT(pipeline->mCurrentTexture->AsWebRenderTextureHost());
+        Range<wr::ImageKey> range_keys(&keys[0], keys.Length());
+        pipeline->mCurrentTexture->PushDisplayItems(builder,
+                                                    wr::ToLayoutRect(rect),
+                                                    wr::ToLayoutRect(rect),
+                                                    pipeline->mFilter,
+                                                    range_keys);
+        HoldExternalImage(pipelineId, epoch, pipeline->mCurrentTexture->AsWebRenderTextureHost());
+      } else {
+        MOZ_ASSERT(keys.Length() == 1);
+        builder.PushImage(wr::ToLayoutRect(rect),
+                          wr::ToLayoutRect(rect),
+                          true,
+                          pipeline->mFilter,
+                          keys[0]);
+      }
     }
 
-    if (pipeline->mUseExternalImage) {
-      MOZ_ASSERT(pipeline->mCurrentTexture->AsWebRenderTextureHost());
-      Range<wr::ImageKey> range_keys(&keys[0], keys.Length());
-      pipeline->mCurrentTexture->PushDisplayItems(builder,
-                                                  wr::ToLayoutRect(rect),
-                                                  wr::ToLayoutRect(rect),
-                                                  pipeline->mFilter,
-                                                  range_keys);
-      HoldExternalImage(pipelineId, epoch, pipeline->mCurrentTexture->AsWebRenderTextureHost());
-    } else {
-      MOZ_ASSERT(keys.Length() == 1);
-      builder.PushImage(wr::ToLayoutRect(rect),
-                        wr::ToLayoutRect(rect),
-                        true,
-                        pipeline->mFilter,
-                        keys[0]);
-    }
     builder.PopStackingContext();
 
     wr::BuiltDisplayList dl;
     wr::LayoutSize builderContentSize;
     builder.Finalize(builderContentSize, dl);
     aTxn.SetDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f),
                         epoch,
                         LayerSize(pipeline->mScBounds.Width(), pipeline->mScBounds.Height()),
--- a/gfx/layers/wr/AsyncImagePipelineManager.h
+++ b/gfx/layers/wr/AsyncImagePipelineManager.h
@@ -150,16 +150,17 @@ private:
       mScBounds = aScBounds;
       mScTransform = aScTransform;
       mScaleToSize = aScaleToSize;
       mFilter = aFilter;
       mMixBlendMode = aMixBlendMode;
     }
 
     bool mInitialised;
+    bool mSentDL;
     bool mIsChanged;
     bool mUseExternalImage;
     LayoutDeviceRect mScBounds;
     gfx::Matrix4x4 mScTransform;
     gfx::MaybeIntSize mScaleToSize;
     wr::ImageRendering mFilter;
     wr::MixBlendMode mMixBlendMode;
     RefPtr<WebRenderImageHost> mImageHost;