Commit 162dcae6 authored by sotaro's avatar sotaro
Browse files

Bug 1385003 - Use a different WebRenderAPI instance for each WebRenderBridgeParent. r=kats

Previously, the WebRenderBridgeParent for each content layer tree would use the
same WebRenderAPI instance as the top-level WebRenderBridgeParent for that window.
However, in order to make the namespacing changes work we now need to use a
separate WebRenderAPI instance for each WebRenderBridgeParent. The content
WebRenderAPIs are cloned from the parent one, so that they all share the same
backend, but can allocate resource IDs in distinct namespaces.

MozReview-Commit-ID: 7VTFL8F09n7

--HG--
extra : rebase_source : 2da1d03abc23bd7852e4b12fe133889bd80cad53
parent 8487cf85
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -463,6 +463,9 @@ CompositorBridgeParent::StopAndClearResources()
    });
    mWrBridge->Destroy();
    mWrBridge = nullptr;
    mAsyncImageManager->Destroy();
    // WebRenderAPI should be already destructed
    mAsyncImageManager = nullptr;
  }

  if (mCompositor) {
@@ -1654,8 +1657,9 @@ CompositorBridgeParent::RecvAdoptChild(const uint64_t& child)
      ScheduleComposition();
    }
    if (mWrBridge && sIndirectLayerTrees[child].mWrBridge) {
      RefPtr<wr::WebRenderAPI> api = mWrBridge->GetWebRenderAPI()->Clone();
      sIndirectLayerTrees[child].mWrBridge->UpdateWebRender(mWrBridge->CompositorScheduler(),
                                                            mWrBridge->GetWebRenderAPI(),
                                                            api,
                                                            mWrBridge->AsyncImageManager(),
                                                            GetAnimationStorage());
      // Pretend we composited, since parent CompositorBridgeParent was replaced.
@@ -1702,8 +1706,8 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel
    *aTextureFactoryIdentifier = TextureFactoryIdentifier(LayersBackend::LAYERS_NONE);
    return mWrBridge;
  }
  RefPtr<AsyncImagePipelineManager> asyncMgr =
    new AsyncImagePipelineManager(api->GetNamespace());
  mAsyncImageManager = new AsyncImagePipelineManager(api->Clone());
  RefPtr<AsyncImagePipelineManager> asyncMgr = mAsyncImageManager;
  api->SetRootPipeline(aPipelineId);
  RefPtr<CompositorAnimationStorage> animStorage = GetAnimationStorage();
  mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, nullptr, Move(api), Move(asyncMgr), Move(animStorage));
@@ -1953,10 +1957,10 @@ CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart,
void
CompositorBridgeParent::NotifyDidCompositeToPipeline(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd)
{
  if (!mWrBridge) {
  if (!mWrBridge || !mAsyncImageManager) {
    return;
  }
  mWrBridge->AsyncImageManager()->Update(aPipelineId, aEpoch);
  mAsyncImageManager->Update(aPipelineId, aEpoch);

  if (mPaused) {
    return;
+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ namespace layers {
class APZCTreeManager;
class APZCTreeManagerParent;
class AsyncCompositionManager;
class AsyncImagePipelineManager;
class Compositor;
class CompositorAnimationStorage;
class CompositorBridgeParent;
@@ -580,6 +581,7 @@ protected:
  RefPtr<HostLayerManager> mLayerManager;
  RefPtr<Compositor> mCompositor;
  RefPtr<AsyncCompositionManager> mCompositionManager;
  RefPtr<AsyncImagePipelineManager> mAsyncImageManager;
  RefPtr<WebRenderBridgeParent> mWrBridge;
  widget::CompositorWidget* mWidget;
  TimeStamp mTestTime;
+1 −1
Original line number Diff line number Diff line
@@ -225,7 +225,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
  }
  WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWrBridge.get();

  RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI();
  RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI()->Clone();
  RefPtr<AsyncImagePipelineManager> holder = root->AsyncImageManager();
  RefPtr<CompositorAnimationStorage> animStorage = cbp->GetAnimationStorage();
  parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder), Move(animStorage));
+22 −20
Original line number Diff line number Diff line
@@ -23,8 +23,9 @@ AsyncImagePipelineManager::AsyncImagePipeline::AsyncImagePipeline()
 , mMixBlendMode(wr::MixBlendMode::Normal)
{}

AsyncImagePipelineManager::AsyncImagePipelineManager(wr::IdNamespace aIdNamespace)
 : mIdNamespace(aIdNamespace)
AsyncImagePipelineManager::AsyncImagePipelineManager(already_AddRefed<wr::WebRenderAPI>&& aApi)
 : mApi(aApi)
 , mIdNamespace(mApi->GetNamespace())
 , mResourceId(0)
 , mAsyncImageEpoch(0)
 , mDestroyed(false)
@@ -38,9 +39,11 @@ AsyncImagePipelineManager::~AsyncImagePipelineManager()
}

void
AsyncImagePipelineManager::Destroy(wr::WebRenderAPI* aApi)
AsyncImagePipelineManager::Destroy()
{
  DeleteOldAsyncImages(aApi);
  MOZ_ASSERT(!mDestroyed);
  DeleteOldAsyncImages();
  mApi = nullptr;
  mDestroyed = true;
}

@@ -51,10 +54,11 @@ AsyncImagePipelineManager::HasKeysToDelete()
}

void
AsyncImagePipelineManager::DeleteOldAsyncImages(wr::WebRenderAPI* aApi)
AsyncImagePipelineManager::DeleteOldAsyncImages()
{
  MOZ_ASSERT(!mDestroyed);
  for (wr::ImageKey key : mKeysToDelete) {
    aApi->DeleteImage(key);
    mApi->DeleteImage(key);
  }
  mKeysToDelete.Clear();
}
@@ -111,7 +115,7 @@ AsyncImagePipelineManager::AddAsyncImagePipeline(const wr::PipelineId& aPipeline
}

void
AsyncImagePipelineManager::RemoveAsyncImagePipeline(wr::WebRenderAPI* aApi, const wr::PipelineId& aPipelineId)
AsyncImagePipelineManager::RemoveAsyncImagePipeline(const wr::PipelineId& aPipelineId)
{
  if (mDestroyed) {
    return;
@@ -121,9 +125,9 @@ AsyncImagePipelineManager::RemoveAsyncImagePipeline(wr::WebRenderAPI* aApi, cons
  if (auto entry = mAsyncImagePipelines.Lookup(id)) {
    AsyncImagePipeline* holder = entry.Data();
    ++mAsyncImageEpoch; // Update webrender epoch
    aApi->ClearRootDisplayList(wr::NewEpoch(mAsyncImageEpoch), aPipelineId);
    mApi->ClearRootDisplayList(wr::NewEpoch(mAsyncImageEpoch), aPipelineId);
    for (wr::ImageKey key : holder->mKeys) {
      aApi->DeleteImage(key);
      mApi->DeleteImage(key);
    }
    entry.Remove();
    RemovePipeline(aPipelineId, wr::NewEpoch(mAsyncImageEpoch));
@@ -155,7 +159,7 @@ AsyncImagePipelineManager::UpdateAsyncImagePipeline(const wr::PipelineId& aPipel
}

bool
AsyncImagePipelineManager::GenerateImageKeyForTextureHost(wr::WebRenderAPI* aApi, TextureHost* aTexture, nsTArray<wr::ImageKey>& aKeys)
AsyncImagePipelineManager::GenerateImageKeyForTextureHost(TextureHost* aTexture, nsTArray<wr::ImageKey>& aKeys)
{
  MOZ_ASSERT(aKeys.IsEmpty());
  MOZ_ASSERT(aTexture);
@@ -166,7 +170,7 @@ AsyncImagePipelineManager::GenerateImageKeyForTextureHost(wr::WebRenderAPI* aApi
    wrTexture->GetWRImageKeys(aKeys, std::bind(&AsyncImagePipelineManager::GenerateImageKey, this));
    MOZ_ASSERT(!aKeys.IsEmpty());
    Range<const wr::ImageKey> keys(&aKeys[0], aKeys.Length());
    wrTexture->AddWRImage(aApi, keys, wrTexture->GetExternalImageKey());
    wrTexture->AddWRImage(mApi, keys, wrTexture->GetExternalImageKey());
    return true;
  } else {
    RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface();
@@ -185,15 +189,14 @@ AsyncImagePipelineManager::GenerateImageKeyForTextureHost(wr::WebRenderAPI* aApi

    wr::ImageKey key = GenerateImageKey();
    aKeys.AppendElement(key);
    aApi->AddImage(key, descriptor, slice);
    mApi->AddImage(key, descriptor, slice);
    dSurf->Unmap();
  }
  return false;
}

bool
AsyncImagePipelineManager::UpdateImageKeys(wr::WebRenderAPI* aApi,
                                           bool& aUseExternalImage,
AsyncImagePipelineManager::UpdateImageKeys(bool& aUseExternalImage,
                                           AsyncImagePipeline* aImageMgr,
                                           nsTArray<wr::ImageKey>& aKeys,
                                           nsTArray<wr::ImageKey>& aKeysToDelete)
@@ -231,7 +234,7 @@ AsyncImagePipelineManager::UpdateImageKeys(wr::WebRenderAPI* aApi,
    return true;
  }

  aUseExternalImage = aImageMgr->mUseExternalImage = GenerateImageKeyForTextureHost(aApi, texture, aKeys);
  aUseExternalImage = aImageMgr->mUseExternalImage = GenerateImageKeyForTextureHost(texture, aKeys);
  MOZ_ASSERT(!aKeys.IsEmpty());
  aImageMgr->mKeys.AppendElements(aKeys);
  aImageMgr->mCurrentTexture = texture;
@@ -239,7 +242,7 @@ AsyncImagePipelineManager::UpdateImageKeys(wr::WebRenderAPI* aApi,
}

void
AsyncImagePipelineManager::ApplyAsyncImages(wr::WebRenderAPI* aApi)
AsyncImagePipelineManager::ApplyAsyncImages()
{
  if (mDestroyed || mAsyncImagePipelines.Count() == 0) {
    return;
@@ -255,8 +258,7 @@ AsyncImagePipelineManager::ApplyAsyncImages(wr::WebRenderAPI* aApi)

    nsTArray<wr::ImageKey> keys;
    bool useExternalImage = false;
    bool updateDisplayList = UpdateImageKeys(aApi,
                                             useExternalImage,
    bool updateDisplayList = UpdateImageKeys(useExternalImage,
                                             pipeline,
                                             keys,
                                             keysToDelete);
@@ -306,11 +308,11 @@ AsyncImagePipelineManager::ApplyAsyncImages(wr::WebRenderAPI* aApi)
    wr::BuiltDisplayList dl;
    wr::LayoutSize builderContentSize;
    builder.Finalize(builderContentSize, dl);
    aApi->SetRootDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f), epoch, LayerSize(pipeline->mScBounds.width, pipeline->mScBounds.height),
    mApi->SetRootDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f), epoch, LayerSize(pipeline->mScBounds.width, pipeline->mScBounds.height),
                             pipelineId, builderContentSize,
                             dl.dl_desc, dl.dl.inner.data, dl.dl.inner.length);
  }
  DeleteOldAsyncImages(aApi);
  DeleteOldAsyncImages();
  mKeysToDelete.SwapElements(keysToDelete);
}

+9 −8
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include "mozilla/gfx/Point.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/Maybe.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsClassHashtable.h"

@@ -34,13 +35,13 @@ class AsyncImagePipelineManager final
public:
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncImagePipelineManager)

  explicit AsyncImagePipelineManager(wr::IdNamespace aIdNamespace);
  explicit AsyncImagePipelineManager(already_AddRefed<wr::WebRenderAPI>&& aApi);

protected:
  ~AsyncImagePipelineManager();

public:
  void Destroy(wr::WebRenderAPI* aApi);
  void Destroy();
  bool HasKeysToDelete();

  void AddPipeline(const wr::PipelineId& aPipelineId);
@@ -70,7 +71,7 @@ public:
  }

  void AddAsyncImagePipeline(const wr::PipelineId& aPipelineId, WebRenderImageHost* aImageHost);
  void RemoveAsyncImagePipeline(wr::WebRenderAPI* aApi, const wr::PipelineId& aPipelineId);
  void RemoveAsyncImagePipeline(const wr::PipelineId& aPipelineId);

  void UpdateAsyncImagePipeline(const wr::PipelineId& aPipelineId,
                                const LayerRect& aScBounds,
@@ -78,7 +79,7 @@ public:
                                const gfx::MaybeIntSize& aScaleToSize,
                                const wr::ImageRendering& aFilter,
                                const wr::MixBlendMode& aMixBlendMode);
  void ApplyAsyncImages(wr::WebRenderAPI* aApi);
  void ApplyAsyncImages();

  void AppendImageCompositeNotification(const ImageCompositeNotificationInfo& aNotification)
  {
@@ -91,7 +92,7 @@ public:
  }

private:
  void DeleteOldAsyncImages(wr::WebRenderAPI* aApi);
  void DeleteOldAsyncImages();

  uint32_t GetNextResourceId() { return ++mResourceId; }
  wr::IdNamespace GetNamespace() { return mIdNamespace; }
@@ -102,7 +103,7 @@ private:
    key.mHandle = GetNextResourceId();
    return key;
  }
  bool GenerateImageKeyForTextureHost(wr::WebRenderAPI* aApi, TextureHost* aTexture, nsTArray<wr::ImageKey>& aKeys);
  bool GenerateImageKeyForTextureHost(TextureHost* aTexture, nsTArray<wr::ImageKey>& aKeys);

  struct ForwardingTextureHost {
    ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture)
@@ -135,12 +136,12 @@ private:
    nsTArray<wr::ImageKey> mKeys;
  };

  bool UpdateImageKeys(wr::WebRenderAPI* aApi,
                       bool& aUseExternalImage,
  bool UpdateImageKeys(bool& aUseExternalImage,
                       AsyncImagePipeline* aImageMgr,
                       nsTArray<wr::ImageKey>& aKeys,
                       nsTArray<wr::ImageKey>& aKeysToDelete);

  RefPtr<wr::WebRenderAPI> mApi;
  wr::IdNamespace mIdNamespace;
  uint32_t mResourceId;

Loading