--- 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()),