Bug 1276811 - Enable TextureClient to be used without CompositableForwarder,r=nical
- Refactoring to make TextureClient use the higher-level
TextureForwarder interface.
MozReview-Commit-ID: EMpsT2exGMf
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -116,19 +116,19 @@ public:
bool Recv__delete__() override { return true; }
ClientIPCAllocator* GetAllocator() { return mTextureForwarder; }
void ActorDestroy(ActorDestroyReason why) override;
bool IPCOpen() const { return mIPCOpen; }
- void Lock() const { if (mCompositableForwarder->UsesImageBridge()) { mLock.Enter(); } }
+ void Lock() const { if (mCompositableForwarder && mCompositableForwarder->UsesImageBridge()) { mLock.Enter(); } }
- void Unlock() const { if (mCompositableForwarder->UsesImageBridge()) { mLock.Leave(); } }
+ void Unlock() const { if (mCompositableForwarder && mCompositableForwarder->UsesImageBridge()) { mLock.Leave(); } }
private:
// AddIPDLReference and ReleaseIPDLReference are only to be called by CreateIPDLActor
// and DestroyIPDLActor, respectively. We intentionally make them private to prevent misuse.
// The purpose of these methods is to be aware of when the IPC system around this
// actor goes down: mIPCOpen is then set to false.
void AddIPDLReference() {
@@ -900,16 +900,61 @@ TextureClient::InitIPDLActor(Compositabl
// since it will be unlocked in TextureClient::Unlock.
if (mIsLocked) {
LockActor();
}
return mActor->IPCOpen();
}
+bool
+TextureClient::InitIPDLActor(TextureForwarder* aForwarder, LayersBackend aBackend)
+{
+ MOZ_ASSERT(aForwarder && aForwarder->GetMessageLoop() == mAllocator->AsClientAllocator()->GetMessageLoop());
+ if (mActor && !mActor->mDestroyed) {
+ CompositableForwarder* currentFwd = mActor->mCompositableForwarder;
+ TextureForwarder* currentTexFwd = mActor->mTextureForwarder;
+
+ if (currentFwd) {
+ gfxCriticalError() << "Attempt to remove a texture from a CompositableForwarder.";
+ return false;
+ }
+
+ if (currentTexFwd && currentTexFwd != aForwarder) {
+ gfxCriticalError() << "Attempt to move a texture to a different channel.";
+ return false;
+ }
+ mActor->mTextureForwarder = aForwarder;
+ return true;
+ }
+ MOZ_ASSERT(!mActor || mActor->mDestroyed, "Cannot use a texture on several IPC channels.");
+
+ SurfaceDescriptor desc;
+ if (!ToSurfaceDescriptor(desc)) {
+ return false;
+ }
+
+ mActor = static_cast<TextureChild*>(aForwarder->CreateTexture(desc,
+ aBackend,
+ GetFlags(),
+ mSerial));
+ MOZ_ASSERT(mActor);
+ mActor->mTextureForwarder = aForwarder;
+ mActor->mTextureClient = this;
+ mActor->mMainThreadOnly = !!(mFlags & TextureFlags::DEALLOCATE_MAIN_THREAD);
+
+ // If the TextureClient is already locked, we have to lock TextureChild's mutex
+ // since it will be unlocked in TextureClient::Unlock.
+ if (mIsLocked) {
+ LockActor();
+ }
+
+ return mActor->IPCOpen();
+}
+
PTextureChild*
TextureClient::GetIPDLActor()
{
return mActor;
}
static inline gfx::BackendType
BackendTypeForBackendSelector(LayersBackend aLayersBackend, BackendSelector aSelector)
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -545,22 +545,32 @@ public:
/**
* If this method retuns false, TextureClient is already added to CompositableClient,
* since its creation or recycling.
*/
bool IsAddedToCompositableClient() const { return mAddedToCompositableClient; }
/**
- * Create and init the TextureChild/Parent IPDL actor pair.
+ * Create and init the TextureChild/Parent IPDL actor pair
+ * with a CompositableForwarder.
+ *
+ * Should be called only once per TextureClient.
+ * The TextureClient must not be locked when calling this method.
+ */
+ bool InitIPDLActor(CompositableForwarder* aForwarder);
+
+ /**
+ * Create and init the TextureChild/Parent IPDL actor pair
+ * with a TextureForwarder.
*
* Should be called only once per TextureClient.
* The TextureClient must not be locked when calling this method.
*/
- bool InitIPDLActor(CompositableForwarder* aForwarder);
+ bool InitIPDLActor(TextureForwarder* aForwarder, LayersBackend aBackendType);
/**
* Return a pointer to the IPDLActor.
*
* This is to be used with IPDL messages only. Do not store the returned
* pointer.
*/
PTextureChild* GetIPDLActor();