diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index 98d789a6b6a2..811f5a6e1646 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -648,6 +648,10 @@ void TextureHost::ReadUnlock() { } } +bool TextureHost::NeedsYFlip() const { + return bool(mFlags & TextureFlags::ORIGIN_BOTTOM_LEFT); +} + bool BufferTextureHost::EnsureWrappingTextureSource() { MOZ_ASSERT(!mHasIntermediateBuffer); diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index e157c03712ca..4ed95765c2af 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -677,6 +677,8 @@ class TextureHost : public AtomicRefCountedWithFinalize { virtual bool SupportsWrNativeTexture() { return false; } + virtual bool NeedsYFlip() const; + protected: virtual void ReadUnlock(); diff --git a/gfx/layers/wr/AsyncImagePipelineManager.cpp b/gfx/layers/wr/AsyncImagePipelineManager.cpp index 006c317f9e8e..8073d2dbe37f 100644 --- a/gfx/layers/wr/AsyncImagePipelineManager.cpp +++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp @@ -261,6 +261,7 @@ Maybe AsyncImagePipelineManager::UpdateImageKeys( bool canUpdate = !!previousTexture && previousTexture->GetSize() == texture->GetSize() && previousTexture->GetFormat() == texture->GetFormat() && + previousTexture->NeedsYFlip() == texture->NeedsYFlip() && aPipeline->mKeys.Length() == numKeys; // Check if WebRenderTextureHostWrapper could be reused. @@ -410,6 +411,12 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline( aPipeline->mIsChanged = false; + gfx::Matrix4x4 scTransform = aPipeline->mScTransform; + if (aPipeline->mCurrentTexture && aPipeline->mCurrentTexture->NeedsYFlip()) { + scTransform.PreTranslate(0, aPipeline->mCurrentTexture->GetSize().height, 0) + .PreScale(1, -1, 1); + } + wr::LayoutSize contentSize{aPipeline->mScBounds.Width(), aPipeline->mScBounds.Height()}; wr::DisplayListBuilder builder(aPipelineId, contentSize); @@ -417,8 +424,7 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline( float opacity = 1.0f; wr::StackingContextParams params; params.opacity = &opacity; - params.mTransformPtr = - aPipeline->mScTransform.IsIdentity() ? nullptr : &aPipeline->mScTransform; + params.mTransformPtr = scTransform.IsIdentity() ? nullptr : &scTransform; params.mix_blend_mode = aPipeline->mMixBlendMode; Maybe referenceFrameId = builder.PushStackingContext( diff --git a/gfx/layers/wr/WebRenderTextureHost.cpp b/gfx/layers/wr/WebRenderTextureHost.cpp index 5a24abfce2a8..e7e8301db871 100644 --- a/gfx/layers/wr/WebRenderTextureHost.cpp +++ b/gfx/layers/wr/WebRenderTextureHost.cpp @@ -169,5 +169,18 @@ bool WebRenderTextureHost::SupportsWrNativeTexture() { return mWrappedTextureHost->SupportsWrNativeTexture(); } +bool WebRenderTextureHost::NeedsYFlip() const { + bool yFlip = TextureHost::NeedsYFlip(); + if (mWrappedTextureHost->AsSurfaceTextureHost()) { + MOZ_ASSERT(yFlip); + // With WebRender, SurfaceTextureHost always requests y-flip. + // But y-flip should not be handled, since + // SurfaceTexture.getTransformMatrix() is not handled yet. + // See Bug 1507076. + yFlip = false; + } + return yFlip; +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/wr/WebRenderTextureHost.h b/gfx/layers/wr/WebRenderTextureHost.h index c35c72f225be..92c00dc0d863 100644 --- a/gfx/layers/wr/WebRenderTextureHost.h +++ b/gfx/layers/wr/WebRenderTextureHost.h @@ -82,6 +82,8 @@ class WebRenderTextureHost : public TextureHost { bool SupportsWrNativeTexture() override; + bool NeedsYFlip() const override; + protected: void CreateRenderTextureHost(const SurfaceDescriptor& aDesc, TextureHost* aTexture); diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp index e97537b66de9..4d9fd0d33589 100644 --- a/layout/generic/nsHTMLCanvasFrame.cpp +++ b/layout/generic/nsHTMLCanvasFrame.cpp @@ -175,10 +175,6 @@ class nsDisplayCanvas final : public nsDisplayItem { scTransform.PreScale(destGFXRect.Width() / canvasSizeInPx.width, destGFXRect.Height() / canvasSizeInPx.height, 1.0f); - if (data->NeedsYFlip()) { - scTransform = scTransform.PreTranslate(0, data->GetSize().height, 0) - .PreScale(1, -1, 1); - } MaybeIntSize scaleToSize; LayoutDeviceRect scBounds(LayoutDevicePoint(0, 0), bounds.Size());