author | sotaro <sotaro.ikeda.g@gmail.com> |
Thu, 16 Nov 2017 14:47:26 +0900 | |
changeset 392194 | 4a74a02c20ba4649bfdb5bdd49f5907c6f22b2d5 |
parent 392193 | 917dfffde62acfc2315de61385f82dfb6f29a440 |
child 392195 | 92235deefc25008210fc2d433cb92174d6adf1b1 |
child 392292 | 3fa17ac9d0ee1b379dd3b27392725d55735be5f4 |
push id | 55477 |
push user | rgurzau@mozilla.com |
push date | Thu, 16 Nov 2017 10:16:50 +0000 |
treeherder | autoland@1dd02399f872 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nical |
bugs | 1411472 |
milestone | 59.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -1879,17 +1879,19 @@ CanvasRenderingContext2D::TrySharedTarge { aOutDT = nullptr; aOutProvider = nullptr; if (!mCanvasElement || !mCanvasElement->OwnerDoc()) { return false; } - if (mBufferProvider && mBufferProvider->GetType() == LayersBackend::LAYERS_CLIENT) { + if (mBufferProvider && + (mBufferProvider->GetType() == LayersBackend::LAYERS_CLIENT || + mBufferProvider->GetType() == LayersBackend::LAYERS_WR)) { // we are already using a shared buffer provider, we are allocating a new one // because the current one failed so let's just fall back to the basic provider. return false; } RefPtr<LayerManager> layerManager = LayerManagerFromCanvasElement(mCanvasElement); if (!layerManager) { @@ -5591,17 +5593,19 @@ CanvasRenderingContext2D::DrawWindow(nsG GlobalAlpha() == 1.0f) { op = UsedOperation(); if (!IsTargetValid()) { aError.Throw(NS_ERROR_FAILURE); return; } } if (op == CompositionOp::OP_OVER && - (!mBufferProvider || mBufferProvider->GetType() != LayersBackend::LAYERS_CLIENT)) + (!mBufferProvider || + (mBufferProvider->GetType() != LayersBackend::LAYERS_CLIENT && + mBufferProvider->GetType() != LayersBackend::LAYERS_WR))) { thebes = gfxContext::CreateOrNull(mTarget); MOZ_ASSERT(thebes); // already checked the draw target above // (in SupportsAzureContentForDrawTarget) thebes->SetMatrix(matrix); } else { IntSize dtSize = IntSize::Ceil(sw, sh); if (!Factory::AllowedSurfaceSize(dtSize)) {
--- a/gfx/layers/PersistentBufferProvider.cpp +++ b/gfx/layers/PersistentBufferProvider.cpp @@ -3,16 +3,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "PersistentBufferProvider.h" #include "Layers.h" #include "mozilla/layers/ShadowLayers.h" +#include "mozilla/layers/TextureClient.h" #include "mozilla/gfx/Logging.h" #include "pratom.h" #include "gfxPlatform.h" namespace mozilla { using namespace gfx; @@ -83,97 +84,108 @@ PersistentBufferProviderBasic::Create(gf return provider.forget(); } //static already_AddRefed<PersistentBufferProviderShared> PersistentBufferProviderShared::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - ShadowLayerForwarder* aFwd) + KnowsCompositor* aKnowsCompositor) { - if (!aFwd || !aFwd->GetTextureForwarder()->IPCOpen()) { + if (!aKnowsCompositor || !aKnowsCompositor->GetTextureForwarder()->IPCOpen()) { return nullptr; } RefPtr<TextureClient> texture = TextureClient::CreateForDrawing( - aFwd, aFormat, aSize, + aKnowsCompositor, aFormat, aSize, BackendSelector::Canvas, TextureFlags::DEFAULT, TextureAllocationFlags::ALLOC_DEFAULT ); if (!texture) { return nullptr; } RefPtr<PersistentBufferProviderShared> provider = - new PersistentBufferProviderShared(aSize, aFormat, aFwd, texture); + new PersistentBufferProviderShared(aSize, aFormat, aKnowsCompositor, texture); return provider.forget(); } PersistentBufferProviderShared::PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - ShadowLayerForwarder* aFwd, + KnowsCompositor* aKnowsCompositor, RefPtr<TextureClient>& aTexture) : mSize(aSize) , mFormat(aFormat) -, mFwd(aFwd) +, mKnowsCompositor(aKnowsCompositor) , mFront(Nothing()) { + MOZ_ASSERT(aKnowsCompositor); if (mTextures.append(aTexture)) { mBack = Some<uint32_t>(0); } MOZ_COUNT_CTOR(PersistentBufferProviderShared); } PersistentBufferProviderShared::~PersistentBufferProviderShared() { MOZ_COUNT_DTOR(PersistentBufferProviderShared); if (IsActivityTracked()) { - mFwd->GetActiveResourceTracker().RemoveObject(this); + mKnowsCompositor->GetActiveResourceTracker()->RemoveObject(this); } Destroy(); } -bool -PersistentBufferProviderShared::SetForwarder(ShadowLayerForwarder* aFwd) +LayersBackend +PersistentBufferProviderShared::GetType() { - MOZ_ASSERT(aFwd); - if (!aFwd) { + if (mKnowsCompositor->GetCompositorBackendType() == LayersBackend::LAYERS_WR) { + return LayersBackend::LAYERS_WR; + } else { + return LayersBackend::LAYERS_CLIENT; + } +} + +bool +PersistentBufferProviderShared::SetKnowsCompositor(KnowsCompositor* aKnowsCompositor) +{ + MOZ_ASSERT(aKnowsCompositor); + if (!aKnowsCompositor) { return false; } - if (mFwd == aFwd) { + if (mKnowsCompositor == aKnowsCompositor) { // The forwarder should not change most of the time. return true; } if (IsActivityTracked()) { - mFwd->GetActiveResourceTracker().RemoveObject(this); + mKnowsCompositor->GetActiveResourceTracker()->RemoveObject(this); } - if (mFwd->GetTextureForwarder() != aFwd->GetTextureForwarder() || - mFwd->GetCompositorBackendType() != aFwd->GetCompositorBackendType()) { + if (mKnowsCompositor->GetTextureForwarder() != aKnowsCompositor->GetTextureForwarder() || + mKnowsCompositor->GetCompositorBackendType() != aKnowsCompositor->GetCompositorBackendType()) { // We are going to be used with an different and/or incompatible forwarder. // This should be extremely rare. We have to copy the front buffer into a // texture that is compatible with the new forwarder. // Grab the current front buffer. RefPtr<TextureClient> prevTexture = GetTexture(mFront); // Get rid of everything else Destroy(); if (prevTexture) { RefPtr<TextureClient> newTexture = TextureClient::CreateForDrawing( - aFwd, mFormat, mSize, + aKnowsCompositor, mFormat, mSize, BackendSelector::Canvas, TextureFlags::DEFAULT, TextureAllocationFlags::ALLOC_DEFAULT ); MOZ_ASSERT(newTexture); if (!newTexture) { return false; @@ -205,43 +217,43 @@ PersistentBufferProviderShared::SetForwa if (!mTextures.append(newTexture)) { return false; } mFront = Some<uint32_t>(mTextures.length() - 1); mBack = mFront; } } - mFwd = aFwd; + mKnowsCompositor = aKnowsCompositor; return true; } TextureClient* PersistentBufferProviderShared::GetTexture(const Maybe<uint32_t>& aIndex) { if (aIndex.isNothing() || !CheckIndex(aIndex.value())) { return nullptr; } return mTextures[aIndex.value()]; } already_AddRefed<gfx::DrawTarget> PersistentBufferProviderShared::BorrowDrawTarget(const gfx::IntRect& aPersistedRect) { - if (!mFwd->GetTextureForwarder()->IPCOpen()) { + if (!mKnowsCompositor->GetTextureForwarder()->IPCOpen()) { return nullptr; } MOZ_ASSERT(!mSnapshot); if (IsActivityTracked()) { - mFwd->GetActiveResourceTracker().MarkUsed(this); + mKnowsCompositor->GetActiveResourceTracker()->MarkUsed(this); } else { - mFwd->GetActiveResourceTracker().AddObject(this); + mKnowsCompositor->GetActiveResourceTracker()->AddObject(this); } if (mDrawTarget) { RefPtr<gfx::DrawTarget> dt(mDrawTarget); return dt.forget(); } auto previousBackBuffer = mBack; @@ -273,17 +285,17 @@ PersistentBufferProviderShared::BorrowDr // We should never need to buffer that many textures, something's wrong. // In theory we throttle the main thread when the compositor can't keep up, // so we shoud never get in a situation where we sent 4 textures to the // compositor and the latter has not released any of them. // In practice, though, the throttling mechanism appears to have some issues, // especially when switching between layer managers (during tab-switch). // To make sure we don't get too far ahead of the compositor, we send a // sync ping to the compositor thread... - mFwd->SyncWithCompositor(); + mKnowsCompositor->SyncWithCompositor(); // ...and try again. for (uint32_t i = 0; i < mTextures.length(); ++i) { if (!mTextures[i]->IsReadLocked()) { gfxCriticalNote << "Managed to allocate after flush."; mBack = Some(i); tex = mTextures[i]; break; } @@ -295,17 +307,17 @@ PersistentBufferProviderShared::BorrowDr // call NotifyInactive to remove some of our textures. NotifyInactive(); // Give up now. The caller can fall-back to a non-shared buffer provider. return nullptr; } } RefPtr<TextureClient> newTexture = TextureClient::CreateForDrawing( - mFwd, mFormat, mSize, + mKnowsCompositor, mFormat, mSize, BackendSelector::Canvas, TextureFlags::DEFAULT, TextureAllocationFlags::ALLOC_DEFAULT ); MOZ_ASSERT(newTexture); if (newTexture) { if (mTextures.append(newTexture)) {
--- a/gfx/layers/PersistentBufferProvider.h +++ b/gfx/layers/PersistentBufferProvider.h @@ -4,31 +4,33 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MOZILLA_GFX_PersistentBUFFERPROVIDER_H #define MOZILLA_GFX_PersistentBUFFERPROVIDER_H #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed, etc +#include "mozilla/layers/KnowsCompositor.h" #include "mozilla/layers/LayersTypes.h" -#include "mozilla/layers/ShadowLayers.h" +#include "mozilla/RefCounted.h" #include "mozilla/gfx/Types.h" #include "mozilla/Vector.h" namespace mozilla { namespace gfx { class SourceSurface; class DrawTarget; } namespace layers { class CopyableCanvasLayer; +class TextureClient; /** * A PersistentBufferProvider is for users which require the temporary use of * a DrawTarget to draw into. When they're done drawing they return the * DrawTarget, when they later need to continue drawing they get a DrawTarget * from the provider again, the provider will guarantee the contents of the * previously returned DrawTarget is persisted into the one newly returned. */ @@ -60,17 +62,17 @@ public: virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() = 0; virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) = 0; virtual TextureClient* GetTextureClient() { return nullptr; } virtual void OnShutdown() {} - virtual bool SetForwarder(ShadowLayerForwarder* aFwd) { return true; } + virtual bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor) { return true; } virtual void ClearCachedResources() {} /** * Return true if this provider preserves the drawing state (clips, transforms, * etc.) across frames. In practice this means users of the provider can skip * popping all of the clips at the end of the frames and pushing them back at * the beginning of the following frames, which can be costly (cf. bug 1294351). @@ -115,54 +117,54 @@ private: class PersistentBufferProviderShared : public PersistentBufferProvider , public ActiveResource { public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderShared, override) static already_AddRefed<PersistentBufferProviderShared> Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - ShadowLayerForwarder* aFwd); + KnowsCompositor* aKnowsCompositor); - virtual LayersBackend GetType() override { return LayersBackend::LAYERS_CLIENT; } + virtual LayersBackend GetType() override; virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(const gfx::IntRect& aPersistedRect) override; virtual bool ReturnDrawTarget(already_AddRefed<gfx::DrawTarget> aDT) override; virtual already_AddRefed<gfx::SourceSurface> BorrowSnapshot() override; virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override; virtual TextureClient* GetTextureClient() override; virtual void NotifyInactive() override; virtual void OnShutdown() override { Destroy(); } - virtual bool SetForwarder(ShadowLayerForwarder* aFwd) override; + virtual bool SetKnowsCompositor(KnowsCompositor* aKnowsCompositor) override; virtual void ClearCachedResources() override; virtual bool PreservesDrawingState() const override { return false; } protected: PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, - ShadowLayerForwarder* aFwd, + KnowsCompositor* aKnowsCompositor, RefPtr<TextureClient>& aTexture); ~PersistentBufferProviderShared(); TextureClient* GetTexture(const Maybe<uint32_t>& aIndex); bool CheckIndex(uint32_t aIndex) { return aIndex < mTextures.length(); } void Destroy(); gfx::IntSize mSize; gfx::SurfaceFormat mFormat; - RefPtr<ShadowLayerForwarder> mFwd; + RefPtr<KnowsCompositor> mKnowsCompositor; Vector<RefPtr<TextureClient>, 4> mTextures; // Offset of the texture in mTextures that the canvas uses. Maybe<uint32_t> mBack; // Offset of the texture in mTextures that is presented to the compositor. Maybe<uint32_t> mFront; RefPtr<gfx::DrawTarget> mDrawTarget; RefPtr<gfx::SourceSurface > mSnapshot;
--- a/gfx/layers/ShareableCanvasRenderer.cpp +++ b/gfx/layers/ShareableCanvasRenderer.cpp @@ -221,17 +221,17 @@ ShareableCanvasRenderer::UpdateComposita if (!IsDirty()) { return; } ResetDirty(); FirePreTransactionCallback(); if (mBufferProvider && mBufferProvider->GetTextureClient()) { - if (!mBufferProvider->SetForwarder(GetForwarder()->AsLayerForwarder())) { + if (!mBufferProvider->SetKnowsCompositor(GetForwarder())) { gfxCriticalNote << "BufferProvider::SetForwarder failed"; return; } mCanvasClient->UpdateFromTexture(mBufferProvider->GetTextureClient()); } else { mCanvasClient->Update(gfx::IntSize(mSize.width, mSize.height), this); }
--- a/gfx/layers/ipc/KnowsCompositor.h +++ b/gfx/layers/ipc/KnowsCompositor.h @@ -4,25 +4,57 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MOZILLA_LAYERS_KNOWSCOMPOSITOR #define MOZILLA_LAYERS_KNOWSCOMPOSITOR #include "mozilla/layers/LayersTypes.h" // for LayersBackend #include "mozilla/layers/CompositorTypes.h" +#include "nsExpirationTracker.h" namespace mozilla { namespace layers { class SyncObjectClient; class TextureForwarder; class LayersIPCActor; /** + * See ActiveResourceTracker below. + */ +class ActiveResource +{ +public: + virtual void NotifyInactive() = 0; + nsExpirationState* GetExpirationState() { return &mExpirationState; } + bool IsActivityTracked() { return mExpirationState.IsTracked(); } +private: + nsExpirationState mExpirationState; +}; + +/** + * A convenience class on top of nsExpirationTracker + */ +class ActiveResourceTracker : public nsExpirationTracker<ActiveResource, 3> +{ +public: + ActiveResourceTracker(uint32_t aExpirationCycle, const char* aName, + nsIEventTarget* aEventTarget) + : nsExpirationTracker(aExpirationCycle, aName, aEventTarget) + {} + + virtual void NotifyExpired(ActiveResource* aResource) override + { + RemoveObject(aResource); + aResource->NotifyInactive(); + } +}; + +/** * An abstract interface for classes that are tied to a specific Compositor across * IPDL and uses TextureFactoryIdentifier to describe this Compositor. */ class KnowsCompositor { public: NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING KnowsCompositor(); @@ -74,20 +106,38 @@ public: bool DeviceCanReset() const { return GetCompositorBackendType() != LayersBackend::LAYERS_BASIC; } int32_t GetSerial() { return mSerial; } /** + * Sends a synchronous ping to the compsoitor. + * + * This is bad for performance and should only be called as a last resort if the + * compositor may be blocked for a long period of time, to avoid that the content + * process accumulates resource allocations that the compositor is not consuming + * and releasing. + */ + virtual void SyncWithCompositor() + { + MOZ_ASSERT_UNREACHABLE("Unimplemented"); + } + + /** * Helpers for finding other related interface. These are infallible. */ virtual TextureForwarder* GetTextureForwarder() = 0; virtual LayersIPCActor* GetLayersIPCActor() = 0; + virtual ActiveResourceTracker* GetActiveResourceTracker() + { + MOZ_ASSERT_UNREACHABLE("Unimplemented"); + return nullptr; + } protected: TextureFactoryIdentifier mTextureFactoryIdentifier; RefPtr<SyncObjectClient> mSyncObject; const int32_t mSerial; static mozilla::Atomic<int32_t> sSerialCounter; };
--- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -21,17 +21,16 @@ #include "mozilla/layers/TextureForwarder.h" #include "mozilla/layers/CompositorTypes.h" // for OpenMode, etc #include "mozilla/layers/CompositorBridgeChild.h" #include "nsCOMPtr.h" // for already_AddRefed #include "nsRegion.h" // for nsIntRegion #include "nsTArrayForwardDeclare.h" // for InfallibleTArray #include "nsIWidget.h" #include <vector> -#include "nsExpirationTracker.h" namespace mozilla { namespace layers { class ClientLayerManager; class CompositorBridgeChild; class FixedSizeSmallShmemSectionAllocator; class ImageContainer; @@ -41,47 +40,16 @@ class LayerTransactionChild; class ShadowableLayer; class SurfaceDescriptor; class TextureClient; class ThebesBuffer; class ThebesBufferData; class Transaction; /** - * See ActiveResourceTracker below. - */ -class ActiveResource -{ -public: - virtual void NotifyInactive() = 0; - nsExpirationState* GetExpirationState() { return &mExpirationState; } - bool IsActivityTracked() { return mExpirationState.IsTracked(); } -private: - nsExpirationState mExpirationState; -}; - -/** - * A convenience class on top of nsExpirationTracker - */ -class ActiveResourceTracker : public nsExpirationTracker<ActiveResource, 3> -{ -public: - ActiveResourceTracker(uint32_t aExpirationCycle, const char* aName, - nsIEventTarget* aEventTarget) - : nsExpirationTracker(aExpirationCycle, aName, aEventTarget) - {} - - virtual void NotifyExpired(ActiveResource* aResource) override - { - RemoveObject(aResource); - aResource->NotifyInactive(); - } -}; - -/** * We want to share layer trees across thread contexts and address * spaces for several reasons; chief among them * * - a parent process can paint a child process's layer tree while * the child process is blocked, say on content script. This is * important on mobile devices where UI responsiveness is key. * * - a dedicated "compositor" process can asynchronously (wrt the @@ -404,30 +372,22 @@ public: return mPaintTiming; } ShadowLayerForwarder* AsLayerForwarder() override { return this; } // Returns true if aSurface wraps a Shmem. static bool IsShmem(SurfaceDescriptor* aSurface); - /** - * Sends a synchronous ping to the compsoitor. - * - * This is bad for performance and should only be called as a last resort if the - * compositor may be blocked for a long period of time, to avoid that the content - * process accumulates resource allocations that the compositor is not consuming - * and releasing. - */ - void SyncWithCompositor(); + void SyncWithCompositor() override; TextureForwarder* GetTextureForwarder() override { return GetCompositorBridgeChild(); } LayersIPCActor* GetLayersIPCActor() override { return this; } - ActiveResourceTracker& GetActiveResourceTracker() { return *mActiveResourceTracker.get(); } + ActiveResourceTracker* GetActiveResourceTracker() override { return mActiveResourceTracker.get(); } CompositorBridgeChild* GetCompositorBridgeChild(); nsIEventTarget* GetEventTarget() { return mEventTarget; }; protected: virtual ~ShadowLayerForwarder();
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp +++ b/gfx/layers/wr/WebRenderBridgeChild.cpp @@ -2,16 +2,17 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/layers/WebRenderBridgeChild.h" #include "gfxPlatform.h" +#include "mozilla/dom/TabGroup.h" #include "mozilla/layers/CompositableClient.h" #include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/layers/ImageDataSerializer.h" #include "mozilla/layers/IpcResourceUpdateQueue.h" #include "mozilla/layers/StackingContextHelper.h" #include "mozilla/layers/PTextureChild.h" #include "mozilla/layers/WebRenderLayerManager.h" #include "mozilla/webrender/WebRenderAPI.h" @@ -31,37 +32,51 @@ WebRenderBridgeChild::WebRenderBridgeChi , mManager(nullptr) , mIPCOpen(false) , mDestroyed(false) , mFontKeysDeleted(0) , mFontInstanceKeysDeleted(0) { } +WebRenderBridgeChild::~WebRenderBridgeChild() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mDestroyed); +} + void WebRenderBridgeChild::Destroy(bool aIsSync) { if (!IPCOpen()) { return; } - // mDestroyed is used to prevent calling Send__delete__() twice. - // When this function is called from CompositorBridgeChild::Destroy(). - mDestroyed = true; - mManager = nullptr; + + DoDestroy(); if (aIsSync) { SendShutdownSync(); } else { SendShutdown(); } } void WebRenderBridgeChild::ActorDestroy(ActorDestroyReason why) { + DoDestroy(); +} + +void +WebRenderBridgeChild::DoDestroy() +{ + // mDestroyed is used to prevent calling Send__delete__() twice. + // When this function is called from CompositorBridgeChild::Destroy(). + // mActiveResourceTracker is not cleared here, since it is + // used by PersistentBufferProviderShared. mDestroyed = true; mManager = nullptr; } void WebRenderBridgeChild::AddWebRenderParentCommand(const WebRenderParentCommand& aCmd) { MOZ_ASSERT(mIsInTransaction || mIsInClearCachedResources); @@ -397,16 +412,25 @@ WebRenderBridgeChild::GetTextureForwarde LayersIPCActor* WebRenderBridgeChild::GetLayersIPCActor() { return static_cast<LayersIPCActor*>(GetCompositorBridgeChild()); } void +WebRenderBridgeChild::SyncWithCompositor() +{ + auto compositorBridge = GetCompositorBridgeChild(); + if (compositorBridge && compositorBridge->IPCOpen()) { + compositorBridge->SendSyncWithCompositor(); + } +} + +void WebRenderBridgeChild::Connect(CompositableClient* aCompositable, ImageContainer* aImageContainer) { MOZ_ASSERT(!mDestroyed); MOZ_ASSERT(aCompositable); static uint64_t sNextID = 1; uint64_t id = sNextID++; @@ -581,18 +605,26 @@ WebRenderBridgeChild::EndClearCachedReso ProcessWebRenderParentCommands(); SendClearCachedResources(); mIsInClearCachedResources = false; } void WebRenderBridgeChild::SetWebRenderLayerManager(WebRenderLayerManager* aManager) { - MOZ_ASSERT(aManager); + MOZ_ASSERT(aManager && !mManager); mManager = aManager; + + nsCOMPtr<nsIEventTarget> eventTarget = nullptr; + if (dom::TabGroup* tabGroup = mManager->GetTabGroup()) { + eventTarget = tabGroup->EventTargetFor(TaskCategory::Other); + } + MOZ_ASSERT(eventTarget || !XRE_IsContentProcess()); + mActiveResourceTracker = MakeUnique<ActiveResourceTracker>( + 1000, "CompositableForwarder", eventTarget); } ipc::IShmemAllocator* WebRenderBridgeChild::GetShmemAllocator() { return static_cast<CompositorBridgeChild*>(Manager()); }
--- a/gfx/layers/wr/WebRenderBridgeChild.h +++ b/gfx/layers/wr/WebRenderBridgeChild.h @@ -83,16 +83,18 @@ public: CompositorBridgeChild* GetCompositorBridgeChild(); wr::PipelineId GetPipeline() { return mPipelineId; } // KnowsCompositor TextureForwarder* GetTextureForwarder() override; LayersIPCActor* GetLayersIPCActor() override; + void SyncWithCompositor() override; + ActiveResourceTracker* GetActiveResourceTracker() override { return mActiveResourceTracker.get(); } void AddPipelineIdForAsyncCompositable(const wr::PipelineId& aPipelineId, const CompositableHandle& aHandlee); void AddPipelineIdForCompositable(const wr::PipelineId& aPipelineId, const CompositableHandle& aHandlee); void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId); wr::ExternalImageId AllocExternalImageIdForCompositable(CompositableClient* aCompositable); @@ -146,17 +148,17 @@ public: void SetWebRenderLayerManager(WebRenderLayerManager* aManager); ipc::IShmemAllocator* GetShmemAllocator(); private: friend class CompositorBridgeChild; - ~WebRenderBridgeChild() {} + ~WebRenderBridgeChild(); wr::ExternalImageId GetNextExternalImageId(); // CompositableForwarder void Connect(CompositableClient* aCompositable, ImageContainer* aImageContainer = nullptr) override; void UseTiledLayerBuffer(CompositableClient* aCompositable, const SurfaceDescriptorTiles& aTiledDescriptor) override; @@ -174,16 +176,18 @@ private: TextureClient* aClientOnBlack, TextureClient* aClientOnWhite) override; void UpdateFwdTransactionId() override; uint64_t GetFwdTransactionId() override; bool InForwarderThread() override; void ActorDestroy(ActorDestroyReason why) override; + void DoDestroy(); + virtual mozilla::ipc::IPCResult RecvWrUpdated(const wr::IdNamespace& aNewIdNamespace) override; void AddIPDLReference() { MOZ_ASSERT(mIPCOpen == false); mIPCOpen = true; AddRef(); } void ReleaseIPDLReference() { @@ -209,14 +213,16 @@ private: bool mIPCOpen; bool mDestroyed; uint32_t mFontKeysDeleted; nsDataHashtable<UnscaledFontHashKey, wr::FontKey> mFontKeys; uint32_t mFontInstanceKeysDeleted; nsDataHashtable<ScaledFontHashKey, wr::FontInstanceKey> mFontInstanceKeys; + + UniquePtr<ActiveResourceTracker> mActiveResourceTracker; }; } // namespace layers } // namespace mozilla #endif // mozilla_layers_WebRenderBridgeChild_h
--- a/gfx/layers/wr/WebRenderCanvasRenderer.cpp +++ b/gfx/layers/wr/WebRenderCanvasRenderer.cpp @@ -3,16 +3,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WebRenderCanvasRenderer.h" #include "GLContext.h" #include "GLScreenBuffer.h" +#include "mozilla/layers/CompositorBridgeChild.h" #include "SharedSurfaceGL.h" #include "WebRenderBridgeChild.h" #include "WebRenderLayerManager.h" namespace mozilla { namespace layers { CompositableForwarder*
--- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -5,16 +5,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WebRenderLayerManager.h" #include "BasicLayers.h" #include "gfxPrefs.h" #include "GeckoProfiler.h" #include "LayersLogging.h" +#include "mozilla/dom/TabChild.h" +#include "mozilla/dom/TabGroup.h" #include "mozilla/gfx/DrawEventRecorder.h" #include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/layers/IpcResourceUpdateQueue.h" #include "mozilla/layers/StackingContextHelper.h" #include "mozilla/layers/TextureClient.h" #include "mozilla/layers/WebRenderBridgeChild.h" #include "mozilla/layers/UpdateImageHelper.h" #include "nsDisplayList.h" @@ -83,16 +85,18 @@ void WebRenderLayerManager::Destroy() { DoDestroy(/* aIsSync */ false); } void WebRenderLayerManager::DoDestroy(bool aIsSync) { + MOZ_ASSERT(NS_IsMainThread()); + if (IsDestroyed()) { return; } LayerManager::Destroy(); if (WrBridge()) { // Just clear ImageKeys, they are deleted during WebRenderAPI destruction. @@ -524,16 +528,27 @@ WebRenderLayerManager::ClearCachedResour void WebRenderLayerManager::WrUpdated() { mWebRenderCommandBuilder.ClearCachedResources(); DiscardLocalImages(); } +dom::TabGroup* +WebRenderLayerManager::GetTabGroup() +{ + if (mWidget) { + if (dom::TabChild* tabChild = mWidget->GetOwningTabChild()) { + return tabChild->TabGroup(); + } + } + return nullptr; +} + void WebRenderLayerManager::UpdateTextureFactoryIdentifier(const TextureFactoryIdentifier& aNewIdentifier) { WrBridge()->IdentifyTextureHost(aNewIdentifier); } TextureFactoryIdentifier WebRenderLayerManager::GetTextureFactoryIdentifier() @@ -603,10 +618,24 @@ bool WebRenderLayerManager::SetPendingScrollUpdateForNextTransaction(FrameMetrics::ViewID aScrollId, const ScrollUpdateInfo& aUpdateInfo) { // If we ever support changing the scroll position in an "empty transactions" // properly in WR we can fill this in. Covered by bug 1382259. return false; } +already_AddRefed<PersistentBufferProvider> +WebRenderLayerManager::CreatePersistentBufferProvider(const gfx::IntSize& aSize, + gfx::SurfaceFormat aFormat) +{ + if (gfxPrefs::PersistentBufferProviderSharedEnabled()) { + RefPtr<PersistentBufferProvider> provider + = PersistentBufferProviderShared::Create(aSize, aFormat, AsKnowsCompositor()); + if (provider) { + return provider.forget(); + } + } + return LayerManager::CreatePersistentBufferProvider(aSize, aFormat); +} + } // namespace layers } // namespace mozilla
--- a/gfx/layers/wr/WebRenderLayerManager.h +++ b/gfx/layers/wr/WebRenderLayerManager.h @@ -25,16 +25,19 @@ #include "nsDisplayList.h" class nsIWidget; namespace mozilla { struct ActiveScrolledRoot; +namespace dom { +class TabGroup; +} namespace layers { class CompositorBridgeChild; class KnowsCompositor; class PCompositorBridgeChild; class WebRenderBridgeChild; class WebRenderParentCommand; @@ -113,16 +116,19 @@ public: virtual void SetNeedsComposite(bool aNeedsComposite) override { mNeedsComposite = aNeedsComposite; } virtual bool NeedsComposite() const override { return mNeedsComposite; } virtual void SetIsFirstPaint() override { mIsFirstPaint = true; } virtual void SetFocusTarget(const FocusTarget& aFocusTarget) override; + virtual already_AddRefed<PersistentBufferProvider> + CreatePersistentBufferProvider(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat) override; + bool AsyncPanZoomEnabled() const override; // adds an imagekey to a list of keys that will be discarded on the next // transaction or destruction void AddImageKeyForDiscard(wr::ImageKey); void DiscardImages(); void DiscardLocalImages(); @@ -151,16 +157,18 @@ public: WebRenderCommandBuilder& CommandBuilder() { return mWebRenderCommandBuilder; } WebRenderUserDataRefTable* GetWebRenderUserDataTable() { return mWebRenderCommandBuilder.GetWebRenderUserDataTable(); } WebRenderScrollData& GetScrollData() { return mScrollData; } void WrUpdated(); void WindowOverlayChanged() { mWindowOverlayChanged = true; } + dom::TabGroup* GetTabGroup(); + private: /** * Take a snapshot of the parent context, and copy * it into mTarget. */ void MakeSnapshotIfRequired(LayoutDeviceIntSize aSize); void ClearLayer(Layer* aLayer);