Bug 1393031 - Begin moving OpAddExternalImage to IpcResourceUpdateQueue and recycle image keys in WebRenderImageLayer. r=jrmuizel

This commit is contained in:
Nicolas Silva 2017-09-14 20:21:36 +02:00
parent 2e704f3c2c
commit 6721e0dbdc
20 changed files with 185 additions and 159 deletions

View File

@ -135,6 +135,7 @@ union OpUpdateResource {
OpDeleteFont; OpDeleteFont;
OpAddFontInstance; OpAddFontInstance;
OpDeleteFontInstance; OpDeleteFontInstance;
OpAddExternalImage;
}; };
} // namespace } // namespace

View File

@ -172,6 +172,12 @@ IpcResourceUpdateQueue::AddBlobImage(ImageKey key, const ImageDescriptor& aDescr
mUpdates.AppendElement(layers::OpAddBlobImage(aDescriptor, bytes, 0, key)); mUpdates.AppendElement(layers::OpAddBlobImage(aDescriptor, bytes, 0, key));
} }
void
IpcResourceUpdateQueue::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey)
{
mUpdates.AppendElement(layers::OpAddExternalImage(aExtId, aKey));
}
void void
IpcResourceUpdateQueue::UpdateImageBuffer(ImageKey aKey, IpcResourceUpdateQueue::UpdateImageBuffer(ImageKey aKey,
const ImageDescriptor& aDescriptor, const ImageDescriptor& aDescriptor,

View File

@ -63,6 +63,8 @@ public:
const ImageDescriptor& aDescriptor, const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes); Range<uint8_t> aBytes);
void AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey);
void UpdateImageBuffer(wr::ImageKey aKey, void UpdateImageBuffer(wr::ImageKey aKey,
const ImageDescriptor& aDescriptor, const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes); Range<uint8_t> aBytes);

View File

@ -17,6 +17,7 @@ namespace layers {
ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer, ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
wr::DisplayListBuilder& aBuilder, wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aStackingContext) const StackingContextHelper& aStackingContext)
: mLayer(aLayer) : mLayer(aLayer)
, mBuilder(&aBuilder) , mBuilder(&aBuilder)
@ -26,7 +27,7 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
if (!mLayer->WrManager()->AsyncPanZoomEnabled()) { if (!mLayer->WrManager()->AsyncPanZoomEnabled()) {
// If APZ is disabled then we don't need to push the scrolling clips. We // If APZ is disabled then we don't need to push the scrolling clips. We
// still want to push the layer's local clip though. // still want to push the layer's local clip though.
PushLayerLocalClip(aStackingContext); PushLayerLocalClip(aStackingContext, aResources);
return; return;
} }
@ -39,7 +40,7 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
// corresponding scroll layer, so that when we set an async scroll position // corresponding scroll layer, so that when we set an async scroll position
// on the scroll layer, the clip isn't affected by it. // on the scroll layer, the clip isn't affected by it.
if (const Maybe<LayerClip>& clip = metadata.GetScrollClip()) { if (const Maybe<LayerClip>& clip = metadata.GetScrollClip()) {
PushLayerClip(clip.ref(), aStackingContext); PushLayerClip(clip.ref(), aStackingContext, aResources);
} }
const FrameMetrics& fm = layer->GetFrameMetrics(i - 1); const FrameMetrics& fm = layer->GetFrameMetrics(i - 1);
@ -48,7 +49,7 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
// If the layer contents are fixed for this metadata onwards, we need // If the layer contents are fixed for this metadata onwards, we need
// to insert the layer's local clip at this point in the clip tree, // to insert the layer's local clip at this point in the clip tree,
// as a child of whatever's on the stack. // as a child of whatever's on the stack.
PushLayerLocalClip(aStackingContext); PushLayerLocalClip(aStackingContext, aResources);
} }
DefineAndPushScrollLayer(fm, aStackingContext); DefineAndPushScrollLayer(fm, aStackingContext);
@ -59,7 +60,7 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
// child layers. So we need to apply this after pushing all the scroll layers, // child layers. So we need to apply this after pushing all the scroll layers,
// which we do above. // which we do above.
if (const Maybe<LayerClip>& scrolledClip = layer->GetScrolledClip()) { if (const Maybe<LayerClip>& scrolledClip = layer->GetScrolledClip()) {
PushLayerClip(scrolledClip.ref(), aStackingContext); PushLayerClip(scrolledClip.ref(), aStackingContext, aResources);
} }
// If the layer is marked as fixed-position, it is fixed relative to something // If the layer is marked as fixed-position, it is fixed relative to something
@ -82,7 +83,7 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
// Default to 0 if there is no ancestor, because 0 refers to the root scrollframe. // Default to 0 if there is no ancestor, because 0 refers to the root scrollframe.
mBuilder->PushClipAndScrollInfo(scrollsWith.valueOr(0), clipId.ptrOr(nullptr)); mBuilder->PushClipAndScrollInfo(scrollsWith.valueOr(0), clipId.ptrOr(nullptr));
} else { } else {
PushLayerLocalClip(aStackingContext); PushLayerLocalClip(aStackingContext, aResources);
} }
} }
@ -273,7 +274,8 @@ ScrollingLayersHelper::DefineAndPushScrollLayer(const FrameMetrics& aMetrics,
} }
void void
ScrollingLayersHelper::PushLayerLocalClip(const StackingContextHelper& aStackingContext) ScrollingLayersHelper::PushLayerLocalClip(const StackingContextHelper& aStackingContext,
wr::IpcResourceUpdateQueue& aResources)
{ {
Layer* layer = mLayer->GetLayer(); Layer* layer = mLayer->GetLayer();
Maybe<ParentLayerRect> clip; Maybe<ParentLayerRect> clip;
@ -285,7 +287,7 @@ ScrollingLayersHelper::PushLayerLocalClip(const StackingContextHelper& aStacking
clip = Some(layer->GetLocalTransformTyped().TransformBounds(mLayer->Bounds())); clip = Some(layer->GetLocalTransformTyped().TransformBounds(mLayer->Bounds()));
} }
if (clip) { if (clip) {
Maybe<wr::WrImageMask> mask = mLayer->BuildWrMaskLayer(aStackingContext); Maybe<wr::WrImageMask> mask = mLayer->BuildWrMaskLayer(aStackingContext, aResources);
LayerRect clipRect = ViewAs<LayerPixel>(clip.ref(), LayerRect clipRect = ViewAs<LayerPixel>(clip.ref(),
PixelCastJustification::MovingDownToChildren); PixelCastJustification::MovingDownToChildren);
mBuilder->PushClip(mBuilder->DefineClip( mBuilder->PushClip(mBuilder->DefineClip(
@ -296,7 +298,8 @@ ScrollingLayersHelper::PushLayerLocalClip(const StackingContextHelper& aStacking
void void
ScrollingLayersHelper::PushLayerClip(const LayerClip& aClip, ScrollingLayersHelper::PushLayerClip(const LayerClip& aClip,
const StackingContextHelper& aSc) const StackingContextHelper& aSc,
wr::IpcResourceUpdateQueue& aResources)
{ {
LayerRect clipRect = IntRectToRect(ViewAs<LayerPixel>(aClip.GetClipRect(), LayerRect clipRect = IntRectToRect(ViewAs<LayerPixel>(aClip.GetClipRect(),
PixelCastJustification::MovingDownToChildren)); PixelCastJustification::MovingDownToChildren));
@ -305,7 +308,7 @@ ScrollingLayersHelper::PushLayerClip(const LayerClip& aClip,
Layer* maskLayer = mLayer->GetLayer()->GetAncestorMaskLayerAt(maskLayerIndex.value()); Layer* maskLayer = mLayer->GetLayer()->GetAncestorMaskLayerAt(maskLayerIndex.value());
WebRenderLayer* maskWrLayer = WebRenderLayer::ToWebRenderLayer(maskLayer); WebRenderLayer* maskWrLayer = WebRenderLayer::ToWebRenderLayer(maskLayer);
// TODO: check this transform is correct in all cases // TODO: check this transform is correct in all cases
mask = maskWrLayer->RenderMaskLayer(aSc, maskLayer->GetTransform()); mask = maskWrLayer->RenderMaskLayer(aSc, maskLayer->GetTransform(), aResources);
} }
mBuilder->PushClip(mBuilder->DefineClip( mBuilder->PushClip(mBuilder->DefineClip(
aSc.ToRelativeLayoutRect(clipRect), nullptr, mask.ptrOr(nullptr))); aSc.ToRelativeLayoutRect(clipRect), nullptr, mask.ptrOr(nullptr)));

View File

@ -29,6 +29,7 @@ class MOZ_RAII ScrollingLayersHelper
public: public:
ScrollingLayersHelper(WebRenderLayer* aLayer, ScrollingLayersHelper(WebRenderLayer* aLayer,
wr::DisplayListBuilder& aBuilder, wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc); const StackingContextHelper& aSc);
ScrollingLayersHelper(nsDisplayItem* aItem, ScrollingLayersHelper(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder, wr::DisplayListBuilder& aBuilder,
@ -52,9 +53,11 @@ private:
WebRenderLayerManager::ClipIdMap& aCache); WebRenderLayerManager::ClipIdMap& aCache);
bool DefineAndPushScrollLayer(const FrameMetrics& aMetrics, bool DefineAndPushScrollLayer(const FrameMetrics& aMetrics,
const StackingContextHelper& aStackingContext); const StackingContextHelper& aStackingContext);
void PushLayerLocalClip(const StackingContextHelper& aStackingContext); void PushLayerLocalClip(const StackingContextHelper& aStackingContext,
wr::IpcResourceUpdateQueue& aResources);
void PushLayerClip(const LayerClip& aClip, void PushLayerClip(const LayerClip& aClip,
const StackingContextHelper& aSc); const StackingContextHelper& aSc,
wr::IpcResourceUpdateQueue& aResources);
WebRenderLayer* mLayer; WebRenderLayer* mLayer;
wr::DisplayListBuilder* mBuilder; wr::DisplayListBuilder* mBuilder;

View File

@ -278,6 +278,13 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
aUpdates.UpdateBlobImage(op.key(), op.descriptor(), bytes); aUpdates.UpdateBlobImage(op.key(), op.descriptor(), bytes);
break; break;
} }
case OpUpdateResource::TOpAddExternalImage: {
const auto& op = cmd.get_OpAddExternalImage();
if (!AddExternalImage(op.externalImageId(), op.key(), aUpdates)) {
return false;
}
break;
}
case OpUpdateResource::TOpAddRawFont: { case OpUpdateResource::TOpAddRawFont: {
const auto& op = cmd.get_OpAddRawFont(); const auto& op = cmd.get_OpAddRawFont();
wr::Vec_u8 bytes; wr::Vec_u8 bytes;
@ -317,6 +324,56 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
return true; return true;
} }
bool
WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey,
wr::ResourceUpdateQueue& aResources)
{
Range<const wr::ImageKey> keys(&aKey, 1);
// Check if key is obsoleted.
if (keys[0].mNamespace != mIdNamespace) {
return true;
}
MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(aExtId)).get());
RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(aExtId));
if (!host) {
NS_ERROR("CompositableHost does not exist");
return false;
}
if (!gfxEnv::EnableWebRenderRecording()) {
TextureHost* texture = host->GetAsTextureHostForComposite();
if (!texture) {
NS_ERROR("TextureHost does not exist");
return false;
}
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
if (wrTexture) {
wrTexture->AddWRImage(aResources, keys, wrTexture->GetExternalImageKey());
return true;
}
}
RefPtr<DataSourceSurface> dSurf = host->GetAsSurface();
if (!dSurf) {
NS_ERROR("TextureHost does not return DataSourceSurface");
return false;
}
DataSourceSurface::MappedSurface map;
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
NS_ERROR("DataSourceSurface failed to map");
return false;
}
IntSize size = dSurf->GetSize();
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
wr::Vec_u8 data;
data.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
aResources.AddImage(keys[0], descriptor, data);
dSurf->Unmap();
return true;
}
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvUpdateResources(nsTArray<OpUpdateResource>&& aResourceUpdates, WebRenderBridgeParent::RecvUpdateResources(nsTArray<OpUpdateResource>&& aResourceUpdates,
nsTArray<ipc::Shmem>&& aResourceData) nsTArray<ipc::Shmem>&& aResourceData)
@ -461,12 +518,37 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
// to early-return from RecvDPEnd without doing so. // to early-return from RecvDPEnd without doing so.
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy); AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
uint32_t wrEpoch = GetNextWrEpoch();
wr::ResourceUpdateQueue resources; wr::ResourceUpdateQueue resources;
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
ProcessWebRenderParentCommands(aCommands, resources);
UpdateResources(aResourceUpdates, aResourceData, resources); UpdateResources(aResourceUpdates, aResourceData, resources);
uint32_t wrEpoch = GetNextWrEpoch(); // If id namespaces do not match, it means the command is obsolete, probably
ProcessWebRenderCommands(aSize, aCommands, wr::NewEpoch(wrEpoch), // because the tab just moved to a new window.
aContentSize, dl, dlDesc, resources, aIdNamespace); // In that case do not send the commands to webrender.
if (mIdNamespace == aIdNamespace) {
if (mWidget) {
LayoutDeviceIntSize size = mWidget->GetClientSize();
mApi->SetWindowParameters(size);
}
gfx::Color color = mWidget ? gfx::Color(0.3f, 0.f, 0.f, 1.f) : gfx::Color(0.f, 0.f, 0.f, 0.f);
mApi->SetDisplayList(color, wr::NewEpoch(wrEpoch), LayerSize(aSize.width, aSize.height),
mPipelineId, aContentSize,
dlDesc, dl.mData, dl.mLength,
resources);
ScheduleComposition();
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
}
}
HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime); HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
mScrollData = aScrollData; mScrollData = aScrollData;
@ -527,49 +609,9 @@ WebRenderBridgeParent::ProcessWebRenderParentCommands(const InfallibleTArray<Web
switch (cmd.type()) { switch (cmd.type()) {
case WebRenderParentCommand::TOpAddExternalImage: { case WebRenderParentCommand::TOpAddExternalImage: {
const OpAddExternalImage& op = cmd.get_OpAddExternalImage(); const OpAddExternalImage& op = cmd.get_OpAddExternalImage();
Range<const wr::ImageKey> keys(&op.key(), 1); if (!AddExternalImage(op.externalImageId(), op.key(), aResources)) {
// Check if key is obsoleted. NS_ERROR("AddExternalImage failed");
if (keys[0].mNamespace != mIdNamespace) {
break;
} }
MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(op.externalImageId())).get());
RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(op.externalImageId()));
if (!host) {
NS_ERROR("CompositableHost does not exist");
break;
}
if (!gfxEnv::EnableWebRenderRecording()) {
TextureHost* texture = host->GetAsTextureHostForComposite();
if (!texture) {
NS_ERROR("TextureHost does not exist");
break;
}
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
if (wrTexture) {
wrTexture->AddWRImage(aResources, keys, wrTexture->GetExternalImageKey());
break;
}
}
RefPtr<DataSourceSurface> dSurf = host->GetAsSurface();
if (!dSurf) {
NS_ERROR("TextureHost does not return DataSourceSurface");
break;
}
DataSourceSurface::MappedSurface map;
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
NS_ERROR("DataSourceSurface failed to map");
break;
}
IntSize size = dSurf->GetSize();
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
wr::Vec_u8 data;
data.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
aResources.AddImage(keys[0], descriptor, data);
dSurf->Unmap();
break; break;
} }
case WebRenderParentCommand::TOpUpdateAsyncImagePipeline: { case WebRenderParentCommand::TOpUpdateAsyncImagePipeline: {
@ -614,40 +656,6 @@ WebRenderBridgeParent::ProcessWebRenderParentCommands(const InfallibleTArray<Web
} }
} }
void
WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
InfallibleTArray<WebRenderParentCommand>& aCommands, const wr::Epoch& aEpoch,
const wr::LayoutSize& aContentSize, const wr::ByteBuffer& dl,
const wr::BuiltDisplayListDescriptor& dlDesc,
wr::ResourceUpdateQueue& aResourceUpdates,
const wr::IdNamespace& aIdNamespace)
{
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
ProcessWebRenderParentCommands(aCommands, aResourceUpdates);
// The command is obsoleted.
// Do not set the command to webrender since it causes crash in webrender.
if (mIdNamespace != aIdNamespace) {
return;
}
if (mWidget) {
LayoutDeviceIntSize size = mWidget->GetClientSize();
mApi->SetWindowParameters(size);
}
gfx::Color color = mWidget ? gfx::Color(0.3f, 0.f, 0.f, 1.f) : gfx::Color(0.f, 0.f, 0.f, 0.f);
mApi->SetDisplayList(color, aEpoch, LayerSize(aSize.width, aSize.height),
mPipelineId, aContentSize,
dlDesc, dl.mData, dl.mLength,
aResourceUpdates);
ScheduleComposition();
if (ShouldParentObserveEpoch()) {
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
}
}
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvGetSnapshot(PTextureParent* aTexture) WebRenderBridgeParent::RecvGetSnapshot(PTextureParent* aTexture)
{ {

View File

@ -192,18 +192,13 @@ private:
bool UpdateResources(const nsTArray<OpUpdateResource>& aResourceUpdates, bool UpdateResources(const nsTArray<OpUpdateResource>& aResourceUpdates,
const nsTArray<ipc::Shmem>& aResourceData, const nsTArray<ipc::Shmem>& aResourceData,
wr::ResourceUpdateQueue& aUpdates); wr::ResourceUpdateQueue& aUpdates);
bool AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey,
wr::ResourceUpdateQueue& aResources);
uint64_t GetLayersId() const; uint64_t GetLayersId() const;
void ProcessWebRenderParentCommands(const InfallibleTArray<WebRenderParentCommand>& aCommands, void ProcessWebRenderParentCommands(const InfallibleTArray<WebRenderParentCommand>& aCommands,
wr::ResourceUpdateQueue& aResources); wr::ResourceUpdateQueue& aResources);
void ProcessWebRenderCommands(const gfx::IntSize &aSize,
InfallibleTArray<WebRenderParentCommand>& commands,
const wr::Epoch& aEpoch,
const wr::LayoutSize& aContentSize,
const wr::ByteBuffer& dl,
const wr::BuiltDisplayListDescriptor& dlDesc,
wr::ResourceUpdateQueue& aResourceUpdates,
const wr::IdNamespace& aIdNamespace);
void ClearResources(); void ClearResources();
uint64_t GetChildLayerObserverEpoch() const { return mChildLayerObserverEpoch; } uint64_t GetChildLayerObserverEpoch() const { return mChildLayerObserverEpoch; }
bool ShouldParentObserveEpoch(); bool ShouldParentObserveEpoch();

View File

@ -50,7 +50,7 @@ WebRenderCanvasLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
transform = Some(GetTransform().PreTranslate(0, mBounds.Height(), 0).PreScale(1, -1, 1)); transform = Some(GetTransform().PreTranslate(0, mBounds.Height(), 0).PreScale(1, -1, 1));
} }
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
StackingContextHelper sc(aSc, aBuilder, this, transform); StackingContextHelper sc(aSc, aBuilder, this, transform);
LayerRect rect(0, 0, mBounds.Width(), mBounds.Height()); LayerRect rect(0, 0, mBounds.Width(), mBounds.Height());

View File

@ -23,7 +23,7 @@ WebRenderColorLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources, wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc) const StackingContextHelper& aSc)
{ {
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
StackingContextHelper sc(aSc, aBuilder, this); StackingContextHelper sc(aSc, aBuilder, this);
LayerRect rect = Bounds(); LayerRect rect = Bounds();

View File

@ -107,7 +107,7 @@ WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
filters.AppendElement(wr::ToWrFilterOp(filter)); filters.AppendElement(wr::ToWrFilterOp(filter));
} }
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
StackingContextHelper sc(aSc, aBuilder, this, animationsId, opacityForSC, transformForSC, filters); StackingContextHelper sc(aSc, aBuilder, this, animationsId, opacityForSC, transformForSC, filters);
LayerRect rect = Bounds(); LayerRect rect = Bounds();
@ -126,7 +126,7 @@ WebRenderRefLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources, wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc) const StackingContextHelper& aSc)
{ {
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
ParentLayerRect bounds = GetLocalTransformTyped().TransformBounds(Bounds()); ParentLayerRect bounds = GetLocalTransformTyped().TransformBounds(Bounds());
// As with WebRenderTextLayer, because we don't push a stacking context for // As with WebRenderTextLayer, because we don't push a stacking context for

View File

@ -32,7 +32,7 @@ WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
return; return;
} }
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
if (mItem) { if (mItem) {
wr::LayoutSize contentSize; // this won't actually be used by anything wr::LayoutSize contentSize; // this won't actually be used by anything

View File

@ -10,6 +10,7 @@
#include "mozilla/gfx/gfxVars.h" #include "mozilla/gfx/gfxVars.h"
#include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/ImageClient.h" #include "mozilla/layers/ImageClient.h"
#include "mozilla/layers/IpcResourceUpdateQueue.h"
#include "mozilla/layers/ScrollingLayersHelper.h" #include "mozilla/layers/ScrollingLayersHelper.h"
#include "mozilla/layers/StackingContextHelper.h" #include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClientRecycleAllocator.h" #include "mozilla/layers/TextureClientRecycleAllocator.h"
@ -24,6 +25,7 @@ using namespace gfx;
WebRenderImageLayer::WebRenderImageLayer(WebRenderLayerManager* aLayerManager) WebRenderImageLayer::WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
: ImageLayer(aLayerManager, static_cast<WebRenderLayer*>(this)) : ImageLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
, mKey(Nothing())
, mImageClientContainerType(CompositableType::UNKNOWN) , mImageClientContainerType(CompositableType::UNKNOWN)
{ {
MOZ_COUNT_CTOR(WebRenderImageLayer); MOZ_COUNT_CTOR(WebRenderImageLayer);
@ -108,6 +110,35 @@ WebRenderImageLayer::SupportsAsyncUpdate()
return false; return false;
} }
Maybe<wr::ImageKey>
WebRenderImageLayer::UpdateImageKey(ImageClientSingle* aImageClient,
ImageContainer* aContainer,
Maybe<wr::ImageKey>& aOldKey,
wr::ExternalImageId& aExternalImageId,
wr::IpcResourceUpdateQueue& aResources)
{
MOZ_ASSERT(aImageClient);
MOZ_ASSERT(aContainer);
bool ret = aImageClient->UpdateImage(aContainer, /* unused */0);
if (!ret || aImageClient->IsEmpty()) {
// Something failed and/or there is no image to show.
if (aOldKey.isSome()) {
aResources.DeleteImage(aOldKey.value());
}
return Nothing();
}
if (aOldKey.isSome()) {
return aOldKey;
}
wr::WrImageKey key = GenerateImageKey();
aResources.AddExternalImage(aExternalImageId, key);
return Some(key);
}
void void
WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder, WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources, wr::IpcResourceUpdateQueue& aResources,
@ -153,7 +184,7 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
// Push IFrame for async image pipeline. // Push IFrame for async image pipeline.
// XXX Remove this once partial display list update is supported. // XXX Remove this once partial display list update is supported.
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
ParentLayerRect bounds = GetLocalTransformTyped().TransformBounds(Bounds()); ParentLayerRect bounds = GetLocalTransformTyped().TransformBounds(Bounds());
@ -209,12 +240,13 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
mKey = UpdateImageKey(mImageClient->AsImageClientSingle(), mKey = UpdateImageKey(mImageClient->AsImageClientSingle(),
mContainer, mContainer,
mKey, mKey,
mExternalImageId.ref()); mExternalImageId.ref(),
aResources);
if (mKey.isNothing()) { if (mKey.isNothing()) {
return; return;
} }
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
StackingContextHelper sc(aSc, aBuilder, this); StackingContextHelper sc(aSc, aBuilder, this);
LayerRect rect(0, 0, size.width, size.height); LayerRect rect(0, 0, size.width, size.height);
@ -238,7 +270,8 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
Maybe<wr::WrImageMask> Maybe<wr::WrImageMask>
WebRenderImageLayer::RenderMaskLayer(const StackingContextHelper& aSc, WebRenderImageLayer::RenderMaskLayer(const StackingContextHelper& aSc,
const gfx::Matrix4x4& aTransform) const gfx::Matrix4x4& aTransform,
wr::IpcResourceUpdateQueue& aResources)
{ {
if (!mContainer) { if (!mContainer) {
return Nothing(); return Nothing();
@ -278,7 +311,8 @@ WebRenderImageLayer::RenderMaskLayer(const StackingContextHelper& aSc,
mKey = UpdateImageKey(mImageClient->AsImageClientSingle(), mKey = UpdateImageKey(mImageClient->AsImageClientSingle(),
mContainer, mContainer,
mKey, mKey,
mExternalImageId.ref()); mExternalImageId.ref(),
aResources);
if (mKey.isNothing()) { if (mKey.isNothing()) {
return Nothing(); return Nothing();
} }

View File

@ -35,7 +35,8 @@ public:
wr::IpcResourceUpdateQueue& aResources, wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc) override; const StackingContextHelper& aSc) override;
Maybe<wr::WrImageMask> RenderMaskLayer(const StackingContextHelper& aSc, Maybe<wr::WrImageMask> RenderMaskLayer(const StackingContextHelper& aSc,
const gfx::Matrix4x4& aTransform) override; const gfx::Matrix4x4& aTransform,
wr::IpcResourceUpdateQueue& aResources) override;
protected: protected:
CompositableType GetImageClientType(); CompositableType GetImageClientType();
@ -43,6 +44,13 @@ protected:
void AddWRVideoImage(size_t aChannelNumber); void AddWRVideoImage(size_t aChannelNumber);
Maybe<wr::ImageKey>
UpdateImageKey(ImageClientSingle* aImageClient,
ImageContainer* aContainer,
Maybe<wr::ImageKey>& aOldKey,
wr::ExternalImageId& aExternalImageId,
wr::IpcResourceUpdateQueue& aResources);
wr::MaybeExternalImageId mExternalImageId; wr::MaybeExternalImageId mExternalImageId;
Maybe<wr::ImageKey> mKey; Maybe<wr::ImageKey> mKey;
RefPtr<ImageClient> mImageClient; RefPtr<ImageClient> mImageClient;

View File

@ -41,12 +41,13 @@ WebRenderLayer::GenerateImageKey()
} }
Maybe<wr::WrImageMask> Maybe<wr::WrImageMask>
WebRenderLayer::BuildWrMaskLayer(const StackingContextHelper& aRelativeTo) WebRenderLayer::BuildWrMaskLayer(const StackingContextHelper& aRelativeTo,
wr::IpcResourceUpdateQueue& aResources)
{ {
if (GetLayer()->GetMaskLayer()) { if (GetLayer()->GetMaskLayer()) {
WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer()); WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer());
gfx::Matrix4x4 transform = maskLayer->GetLayer()->GetTransform(); gfx::Matrix4x4 transform = maskLayer->GetLayer()->GetTransform();
return maskLayer->RenderMaskLayer(aRelativeTo, transform); return maskLayer->RenderMaskLayer(aRelativeTo, transform, aResources);
} }
return Nothing(); return Nothing();
@ -81,41 +82,6 @@ WebRenderLayer::BoundsForStackingContext()
return bounds; return bounds;
} }
Maybe<wr::ImageKey>
WebRenderLayer::UpdateImageKey(ImageClientSingle* aImageClient,
ImageContainer* aContainer,
Maybe<wr::ImageKey>& aOldKey,
wr::ExternalImageId& aExternalImageId)
{
MOZ_ASSERT(aImageClient);
MOZ_ASSERT(aContainer);
uint32_t oldCounter = aImageClient->GetLastUpdateGenerationCounter();
bool ret = aImageClient->UpdateImage(aContainer, /* unused */0);
if (!ret || aImageClient->IsEmpty()) {
// Delete old key
if (aOldKey.isSome()) {
WrManager()->AddImageKeyForDiscard(aOldKey.value());
}
return Nothing();
}
// Reuse old key if generation is not updated.
if (oldCounter == aImageClient->GetLastUpdateGenerationCounter() && aOldKey.isSome()) {
return aOldKey;
}
// Delete old key, we are generating a new key.
if (aOldKey.isSome()) {
WrManager()->AddImageKeyForDiscard(aOldKey.value());
}
wr::WrImageKey key = GenerateImageKey();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(aExternalImageId, key));
return Some(key);
}
void void
WebRenderLayer::DumpLayerInfo(const char* aLayerType, const LayerRect& aRect) WebRenderLayer::DumpLayerInfo(const char* aLayerType, const LayerRect& aRect)
{ {

View File

@ -28,7 +28,8 @@ public:
wr::IpcResourceUpdateQueue& aResources, wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc) = 0; const StackingContextHelper& aSc) = 0;
virtual Maybe<wr::WrImageMask> RenderMaskLayer(const StackingContextHelper& aSc, virtual Maybe<wr::WrImageMask> RenderMaskLayer(const StackingContextHelper& aSc,
const gfx::Matrix4x4& aTransform) const gfx::Matrix4x4& aTransform,
wr::IpcResourceUpdateQueue& aResources)
{ {
MOZ_ASSERT(false); MOZ_ASSERT(false);
return Nothing(); return Nothing();
@ -41,11 +42,6 @@ public:
return static_cast<WebRenderLayer*>(aLayer->ImplData()); return static_cast<WebRenderLayer*>(aLayer->ImplData());
} }
Maybe<wr::ImageKey> UpdateImageKey(ImageClientSingle* aImageClient,
ImageContainer* aContainer,
Maybe<wr::ImageKey>& aOldKey,
wr::ExternalImageId& aExternalImageId);
WebRenderLayerManager* WrManager(); WebRenderLayerManager* WrManager();
WebRenderBridgeChild* WrBridge(); WebRenderBridgeChild* WrBridge();
wr::WrImageKey GenerateImageKey(); wr::WrImageKey GenerateImageKey();
@ -58,7 +54,8 @@ public:
// that we want this mask to be relative to. This is usually the stacking // that we want this mask to be relative to. This is usually the stacking
// context of the *parent* layer of |this|, because that is what the mask // context of the *parent* layer of |this|, because that is what the mask
// is relative to in the layer tree. // is relative to in the layer tree.
Maybe<wr::WrImageMask> BuildWrMaskLayer(const StackingContextHelper& aRelativeTo); Maybe<wr::WrImageMask> BuildWrMaskLayer(const StackingContextHelper& aRelativeTo,
wr::IpcResourceUpdateQueue& aResources);
protected: protected:
BoundsTransformMatrix BoundsTransform(); BoundsTransformMatrix BoundsTransform();

View File

@ -91,16 +91,18 @@ WebRenderPaintedLayer::UpdateImageClient()
void void
WebRenderPaintedLayer::CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder, WebRenderPaintedLayer::CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc) const StackingContextHelper& aSc)
{ {
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
StackingContextHelper sc(aSc, aBuilder, this); StackingContextHelper sc(aSc, aBuilder, this);
LayerRect rect = Bounds(); LayerRect rect = Bounds();
DumpLayerInfo("PaintedLayer", rect); DumpLayerInfo("PaintedLayer", rect);
wr::WrImageKey key = GenerateImageKey(); wr::WrImageKey key = GenerateImageKey();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key)); aResources.AddExternalImage(mExternalImageId.value(), key);
// TODO: reuse image keys!
WrManager()->AddImageKeyForDiscard(key); WrManager()->AddImageKeyForDiscard(key);
wr::LayoutRect r = sc.ToRelativeLayoutRect(rect); wr::LayoutRect r = sc.ToRelativeLayoutRect(rect);
@ -161,7 +163,7 @@ WebRenderPaintedLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
MOZ_ASSERT(mImageContainer->HasCurrentImage()); MOZ_ASSERT(mImageContainer->HasCurrentImage());
} }
CreateWebRenderDisplayList(aBuilder, aSc); CreateWebRenderDisplayList(aBuilder, aResources, aSc);
} }
void void

View File

@ -57,6 +57,7 @@ private:
bool SetupExternalImages(); bool SetupExternalImages();
bool UpdateImageClient(); bool UpdateImageClient();
void CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder, void CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc); const StackingContextHelper& aSc);
void ClearWrResources(); void ClearWrResources();
}; };

View File

@ -86,7 +86,7 @@ WebRenderPaintedLayerBlob::RenderLayer(wr::DisplayListBuilder& aBuilder,
mImageBounds = visibleRegion.GetBounds(); mImageBounds = visibleRegion.GetBounds();
} }
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
StackingContextHelper sc(aSc, aBuilder, this); StackingContextHelper sc(aSc, aBuilder, this);
LayerRect rect = Bounds(); LayerRect rect = Bounds();
DumpLayerInfo("PaintedLayer", rect); DumpLayerInfo("PaintedLayer", rect);

View File

@ -27,7 +27,7 @@ WebRenderTextLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
return; return;
} }
ScrollingLayersHelper scroller(this, aBuilder, aSc); ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc);
LayerRect rect = LayerRect::FromUnknownRect( LayerRect rect = LayerRect::FromUnknownRect(
// I am not 100% sure this is correct, but it probably is. Because: // I am not 100% sure this is correct, but it probably is. Because:

View File

@ -155,7 +155,7 @@ public:
// Push IFrame for async image pipeline. // Push IFrame for async image pipeline.
// XXX Remove this once partial display list update is supported. // XXX Remove this once partial display list update is supported.
/* ScrollingLayersHelper scroller(this, aBuilder, aSc); */ /* ScrollingLayersHelper scroller(this, aBuilder, aResources, aSc); */
nsIntSize canvasSizeInPx = data->GetSize(); nsIntSize canvasSizeInPx = data->GetSize();
IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx); IntrinsicSize intrinsicSize = IntrinsicSizeFromCanvasSize(canvasSizeInPx);
nsSize intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx); nsSize intrinsicRatio = IntrinsicRatioFromCanvasSize(canvasSizeInPx);