diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index db59553e8c95..872f968e5468 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -290,7 +290,6 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize, for (InfallibleTArray::index_type i = 0; i < aCommands.Length(); ++i) { const WebRenderParentCommand& cmd = aCommands[i]; - switch (cmd.type()) { case WebRenderParentCommand::TOpAddExternalImage: { const OpAddExternalImage& op = cmd.get_OpAddExternalImage(); @@ -332,7 +331,7 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize, } IntSize size = dSurf->GetSize(); - wr::ImageDescriptor descriptor(size, map.mStride, SurfaceFormat::B8G8R8A8); + wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat()); auto slice = Range(map.mData, size.height * map.mStride); mApi->AddImage(key, descriptor, slice); diff --git a/gfx/layers/wr/WebRenderImageLayer.cpp b/gfx/layers/wr/WebRenderImageLayer.cpp index a7c2a5c76fba..b06672bf3abe 100644 --- a/gfx/layers/wr/WebRenderImageLayer.cpp +++ b/gfx/layers/wr/WebRenderImageLayer.cpp @@ -170,5 +170,64 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) //mContainer->SetImageFactory(originalIF); } +Maybe +WebRenderImageLayer::RenderMaskLayer() +{ + if (!mContainer) { + return Nothing(); + } + + CompositableType type = GetImageClientType(); + if (type == CompositableType::UNKNOWN) { + return Nothing(); + } + + MOZ_ASSERT(GetImageClientType() != CompositableType::UNKNOWN); + + if (GetImageClientType() == CompositableType::IMAGE && !mImageClient) { + mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE, + WrBridge(), + TextureFlags::DEFAULT); + if (!mImageClient) { + return Nothing(); + } + mImageClient->Connect(); + } + + if (!mExternalImageId) { + if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) { + MOZ_ASSERT(!mImageClient); + mExternalImageId = WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle()); + } else { + // Handle CompositableType::IMAGE case + MOZ_ASSERT(mImageClient); + mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient); + } + } + MOZ_ASSERT(mExternalImageId); + + // XXX Not good for async ImageContainer case. + AutoLockImage autoLock(mContainer); + Image* image = autoLock.GetImage(); + if (!image) { + return Nothing(); + } + if (mImageClient && !mImageClient->UpdateImage(mContainer, /* unused */0)) { + return Nothing(); + } + + WrImageKey key; + key.mNamespace = WrBridge()->GetNamespace(); + key.mHandle = WrBridge()->GetNextResourceId(); + WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key)); + + gfx::IntSize size = image->GetSize(); + WrImageMask imageMask; + imageMask.image = key; + imageMask.rect = wr::ToWrRect(Rect(0, 0, size.width, size.height)); + imageMask.repeat = false; + return Some(imageMask); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/wr/WebRenderImageLayer.h b/gfx/layers/wr/WebRenderImageLayer.h index 96aab5fe7103..93caacf7dae5 100644 --- a/gfx/layers/wr/WebRenderImageLayer.h +++ b/gfx/layers/wr/WebRenderImageLayer.h @@ -33,6 +33,7 @@ protected: public: Layer* GetLayer() override { return this; } void RenderLayer(wr::DisplayListBuilder& aBuilder) override; + Maybe RenderMaskLayer() override; protected: CompositableType GetImageClientType(); diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index 5b50325c8848..757eacb72617 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -109,40 +109,14 @@ WebRenderLayer::TransformedVisibleBoundsRelativeToParent() } Maybe -WebRenderLayer::BuildWrMaskLayer() { - Maybe mask = Nothing(); - WrImageMask imageMask; - Layer* maskLayer = GetLayer()->GetMaskLayer(); - - if (maskLayer) { - RefPtr surface = WebRenderLayer::ToWebRenderLayer(maskLayer)->GetAsSourceSurface(); - if (surface) { - Matrix transform; - Matrix4x4 effectiveTransform = maskLayer->GetEffectiveTransform(); - DebugOnly maskIs2D = effectiveTransform.CanDraw2D(&transform); - NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!"); - //XXX: let's assert that the mask transform is the same as the layer transform - //transform.PostTranslate(-aDeviceOffset.x, -aDeviceOffset.y); - { - RefPtr dataSurface = surface->GetDataSurface(); - DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::MapType::READ); - gfx::IntSize size = surface->GetSize(); - MOZ_RELEASE_ASSERT(surface->GetFormat() == SurfaceFormat::A8, "bad format"); - wr::ByteBuffer buf(size.height * map.GetStride(), map.GetData()); - WrImageKey maskKey; - maskKey.mNamespace = WrBridge()->GetNamespace(); - maskKey.mHandle = WrBridge()->GetNextResourceId(); - WrBridge()->SendAddImage(maskKey, size, map.GetStride(), SurfaceFormat::A8, buf); - - imageMask.image = maskKey; - imageMask.rect = wr::ToWrRect(Rect(0, 0, size.width, size.height)); - imageMask.repeat = false; - WrManager()->AddImageKeyForDiscard(maskKey); - mask = Some(imageMask); - } - } +WebRenderLayer::BuildWrMaskLayer() +{ + if (GetLayer()->GetMaskLayer()) { + WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer()); + return maskLayer->RenderMaskLayer(); } - return mask; + + return Nothing(); } gfx::Rect diff --git a/gfx/layers/wr/WebRenderLayerManager.h b/gfx/layers/wr/WebRenderLayerManager.h index 76f4f343ace4..dd04c4cbe8b8 100644 --- a/gfx/layers/wr/WebRenderLayerManager.h +++ b/gfx/layers/wr/WebRenderLayerManager.h @@ -30,6 +30,11 @@ class WebRenderLayer public: virtual Layer* GetLayer() = 0; virtual void RenderLayer(wr::DisplayListBuilder& aBuilder) = 0; + virtual Maybe RenderMaskLayer() + { + MOZ_ASSERT(false); + return Nothing(); + } virtual already_AddRefed GetAsSourceSurface() { return nullptr; } static inline WebRenderLayer* @@ -54,7 +59,6 @@ protected: gfx::Rect GetWrClipRect(gfx::Rect& aRect); void DumpLayerInfo(const char* aLayerType, gfx::Rect& aRect); Maybe BuildWrMaskLayer(); - }; class WebRenderLayerManager final : public LayerManager