Bug 1276811 - Enable TextureClient to be used without CompositableForwarder,r=nical draft
authorKearwood (Kip) Gilbert <kgilbert@mozilla.com>
Fri, 27 May 2016 13:49:30 -0700
changeset 382847 09d9110ad3fdffabe9e54eed13ef827893e568f4
parent 382798 82e1f1b9c0559f38a8460e2f2f3044de4c7712d6
child 524311 5098ed4ba3716eb5af2c1bcfad720dcb23b1fac6
push id21846
push userkgilbert@mozilla.com
push dateThu, 30 Jun 2016 17:16:16 +0000
reviewersnical
bugs1276811
milestone50.0a1
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
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
--- 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();