Bug 916118 - Simplify the TextureClient deallocation protocol. r=nrc
authorNicolas Silva <nical@mozilla.com>
Wed, 02 Oct 2013 13:52:04 -0700
changeset 149764 477781ec7d38
parent 149763 3cf52700118c
child 149765 c87681163457
push id25401
push userphilringnalda@gmail.com
push date2013-10-03 14:59 +0000
treeherdermozilla-central@51b36c5fd45f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnrc
bugs916118
milestone27.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
Bug 916118 - Simplify the TextureClient deallocation protocol. r=nrc
gfx/layers/CompositorTypes.h
gfx/layers/GrallocImages.cpp
gfx/layers/LayersLogging.cpp
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/ClientCanvasLayer.cpp
gfx/layers/client/CompositableClient.cpp
gfx/layers/client/ContentClient.cpp
gfx/layers/client/ContentClient.h
gfx/layers/client/ImageClient.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/composite/CompositableHost.cpp
gfx/layers/ipc/CompositableTransactionParent.cpp
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/opengl/TextureClientOGL.cpp
--- a/gfx/layers/CompositorTypes.h
+++ b/gfx/layers/CompositorTypes.h
@@ -54,38 +54,36 @@ const TextureFlags TEXTURE_ON_WHITE     
  // A texture host on black for component alpha
 const TextureFlags TEXTURE_ON_BLACK           = 1 << 14;
 // A texture host that supports tiling
 const TextureFlags TEXTURE_TILE               = 1 << 15;
 // Texture contents should be initialized
 // from the previous texture.
 const TextureFlags TEXTURE_COPY_PREVIOUS      = 1 << 24;
 // Who is responsible for deallocating the shared data.
-// if none of the following two flags is set, the shared data will not be
-// deallocated by the layers system. It is not necessarily a leak, it could
-// be a choice from another part of gecko that wants to keep the data alive
-// for some reason. The default behaviour is to deallocate on the host side.
+// if TEXTURE_DEALLOCATE_CLIENT is set, the shared data is deallocated on the
+// client side and requires some extra synchronizaion to ensure race-free
+// deallocation.
+// The default behaviour is to deallocate on the host side.
 const TextureFlags TEXTURE_DEALLOCATE_CLIENT  = 1 << 25;
-const TextureFlags TEXTURE_DEALLOCATE_HOST    = 1 << 26;
 // After being shared ith the compositor side, an immutable texture is never
 // modified, it can only be read. It is safe to not Lock/Unlock immutable
 // textures.
 const TextureFlags TEXTURE_IMMUTABLE          = 1 << 27;
 // The contents of the texture must be uploaded or copied immediately
 // during the transaction, because the producer may want to write
 // to it again.
 const TextureFlags TEXTURE_IMMEDIATE_UPLOAD   = 1 << 28;
 // The texture is going to be used as part of a double
 // buffered pair, and so we can guarantee that the producer/consumer
 // won't be racing to access its contents.
 const TextureFlags TEXTURE_DOUBLE_BUFFERED    = 1 << 29;
 
 // the default flags
-const TextureFlags TEXTURE_FLAGS_DEFAULT = TEXTURE_DEALLOCATE_HOST
-                                         | TEXTURE_FRONT;
+const TextureFlags TEXTURE_FLAGS_DEFAULT = TEXTURE_FRONT;
 
 static inline bool
 TextureRequiresLocking(TextureFlags aFlags)
 {
   // If we're not double buffered, or uploading
   // within a transaction, then we need to support
   // locking correctly.
   return !(aFlags & (TEXTURE_IMMEDIATE_UPLOAD |
--- a/gfx/layers/GrallocImages.cpp
+++ b/gfx/layers/GrallocImages.cpp
@@ -285,18 +285,17 @@ TextureClient*
 GrallocImage::GetTextureClient()
 {
   if (!mTextureClient) {
     const SurfaceDescriptor& sd = GetSurfaceDescriptor();
     if (sd.type() != SurfaceDescriptor::TSurfaceDescriptorGralloc) {
       return nullptr;
     }
     const SurfaceDescriptorGralloc& desc = sd.get_SurfaceDescriptorGralloc();
-    TextureFlags flags = desc.external() ? TEXTURE_DEALLOCATE_CLIENT
-                                         : TEXTURE_DEALLOCATE_HOST;
+    TextureFlags flags = desc.external() ? TEXTURE_DEALLOCATE_CLIENT : 0;
     if (desc.isRBSwapped()) {
       flags |= TEXTURE_RB_SWAPPED;
     }
     GrallocBufferActor* actor = static_cast<GrallocBufferActor*>(desc.bufferChild());
     mTextureClient = new GrallocTextureClientOGL(actor,
                                                  gfx::ToIntSize(mSize),
                                                  flags);
     mTextureClient->SetGraphicBufferLocked(mGraphicBuffer);
--- a/gfx/layers/LayersLogging.cpp
+++ b/gfx/layers/LayersLogging.cpp
@@ -220,17 +220,16 @@ AppendToString(nsACString& s, TextureFla
   } \
 }
     bool previous = false;
     AppendFlag(TEXTURE_USE_NEAREST_FILTER);
     AppendFlag(TEXTURE_NEEDS_Y_FLIP);
     AppendFlag(TEXTURE_DISALLOW_BIGIMAGE);
     AppendFlag(TEXTURE_ALLOW_REPEAT);
     AppendFlag(TEXTURE_NEW_TILE);
-    AppendFlag(TEXTURE_DEALLOCATE_HOST);
 
 #undef AppendFlag
   }
   return s += sfx;
 }
 
 nsACString&
 AppendToString(nsACString& s, mozilla::gfx::SurfaceFormat format,
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -37,21 +37,21 @@ namespace layers {
 
 /* static */ TemporaryRef<CanvasClient>
 CanvasClient::CreateCanvasClient(CanvasClientType aType,
                                  CompositableForwarder* aForwarder,
                                  TextureFlags aFlags)
 {
   if (aType == CanvasClientGLContext &&
       aForwarder->GetCompositorBackendType() == LAYERS_OPENGL) {
-    aFlags &= ~TEXTURE_DEALLOCATE_HOST;
+    aFlags |= TEXTURE_DEALLOCATE_CLIENT;
     return new DeprecatedCanvasClientSurfaceStream(aForwarder, aFlags);
   }
   if (gfxPlatform::GetPlatform()->UseDeprecatedTextures()) {
-    aFlags &= ~TEXTURE_DEALLOCATE_HOST;
+    aFlags |= TEXTURE_DEALLOCATE_CLIENT;
     return new DeprecatedCanvasClient2D(aForwarder, aFlags);
   }
   return new CanvasClient2D(aForwarder, aFlags);
 }
 
 void
 CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
 {
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -93,22 +93,22 @@ ClientCanvasLayer::RenderLayer()
   
   if (!mCanvasClient) {
     TextureFlags flags = TEXTURE_IMMEDIATE_UPLOAD;
     if (mNeedsYFlip) {
       flags |= TEXTURE_NEEDS_Y_FLIP;
     }
 
     if (!mGLContext) {
+      // We don't support locking for buffer surfaces currently
+      flags |= TEXTURE_IMMEDIATE_UPLOAD;
+    } else {
       // GLContext's SurfaceStream handles ownership itself,
       // and doesn't require layers to do any deallocation.
-      flags |= TEXTURE_DEALLOCATE_HOST;
-
-      // We don't support locking for buffer surfaces currently
-      flags |= TEXTURE_IMMEDIATE_UPLOAD;
+      flags |= TEXTURE_DEALLOCATE_CLIENT;
     }
     mCanvasClient = CanvasClient::CreateCanvasClient(GetCanvasClientType(),
                                                      ClientManager(), flags);
     if (!mCanvasClient) {
       return;
     }
     if (HasShadow()) {
       mCanvasClient->Connect();
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -226,17 +226,17 @@ CompositableClient::AddTextureClient(Tex
 }
 
 void
 CompositableClient::RemoveTextureClient(TextureClient* aClient)
 {
   MOZ_ASSERT(aClient);
   mTexturesToRemove.AppendElement(TextureIDAndFlags(aClient->GetID(),
                                                     aClient->GetFlags()));
-  if (!(aClient->GetFlags() & TEXTURE_DEALLOCATE_HOST)) {
+  if (aClient->GetFlags() & TEXTURE_DEALLOCATE_CLIENT) {
     TextureClientData* data = aClient->DropTextureData();
     if (data) {
       mTexturesToRemoveCallbacks[aClient->GetID()] = data;
     }
   }
   aClient->ClearID();
   aClient->MarkInvalid();
 }
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -196,17 +196,17 @@ ContentClientRemoteBuffer::BuildDeprecat
     if (mDeprecatedTextureClientOnWhite) {
       mOldTextures.AppendElement(mDeprecatedTextureClientOnWhite);
     }
     DestroyBuffers();
   }
 
   mContentType = aType;
   mSize = gfx::IntSize(aRect.width, aRect.height);
-  mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST;
+  mTextureInfo.mTextureFlags = aFlags & ~TEXTURE_DEALLOCATE_CLIENT;
 
   if (!CreateAndAllocateDeprecatedTextureClient(mDeprecatedTextureClient)) {
     return;
   }
   
   if (aFlags & BUFFER_COMPONENT_ALPHA) {
     if (!CreateAndAllocateDeprecatedTextureClient(mDeprecatedTextureClientOnWhite)) {
       mDeprecatedTextureClient->SetFlags(0);
--- a/gfx/layers/client/ContentClient.h
+++ b/gfx/layers/client/ContentClient.h
@@ -399,17 +399,17 @@ private:
 
   enum BufferType{
     BUFFER_BLACK,
     BUFFER_WHITE
   };
 
   void NotifyBufferCreated(ContentType aType, uint32_t aFlags)
   {
-    mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST;
+    mTextureInfo.mTextureFlags = aFlags & ~TEXTURE_DEALLOCATE_CLIENT;
     mContentType = aType;
 
     mForwarder->CreatedIncrementalBuffer(this,
                                          mTextureInfo,
                                          mBufferRect);
 
   }
 
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -160,17 +160,17 @@ ImageClientSingle::UpdateImage(ImageCont
 
     if (mFrontBuffer && mFrontBuffer->IsImmutable()) {
       RemoveTextureClient(mFrontBuffer);
       mFrontBuffer = nullptr;
     }
 
     bool bufferCreated = false;
     if (!mFrontBuffer) {
-      mFrontBuffer = CreateBufferTextureClient(gfx::FORMAT_YUV, TEXTURE_DEALLOCATE_HOST);
+      mFrontBuffer = CreateBufferTextureClient(gfx::FORMAT_YUV, TEXTURE_FLAGS_DEFAULT);
       gfx::IntSize ySize(data->mYSize.width, data->mYSize.height);
       gfx::IntSize cbCrSize(data->mCbCrSize.width, data->mCbCrSize.height);
       if (!mFrontBuffer->AsTextureClientYCbCr()->AllocateForYCbCr(ySize, cbCrSize, data->mStereoMode)) {
         mFrontBuffer = nullptr;
         return false;
       }
       bufferCreated = true;
     }
@@ -221,17 +221,17 @@ ImageClientSingle::UpdateImage(ImageCont
       mFrontBuffer = nullptr;
     }
 
     bool bufferCreated = false;
     if (!mFrontBuffer) {
       gfxImageFormat format
         = gfxPlatform::GetPlatform()->OptimalFormatForContent(surface->GetContentType());
       mFrontBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format),
-                                               TEXTURE_DEALLOCATE_HOST);
+                                               TEXTURE_FLAGS_DEFAULT);
       MOZ_ASSERT(mFrontBuffer->AsTextureClientSurface());
       mFrontBuffer->AsTextureClientSurface()->AllocateForSurface(size);
 
       bufferCreated = true;
     }
 
     if (!mFrontBuffer->Lock(OPEN_READ_WRITE)) {
       return false;
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -394,17 +394,17 @@ DeprecatedTextureClientShmem::ReleaseRes
 {
   if (mSurface) {
     mSurface = nullptr;
     mSurfaceAsImage = nullptr;
 
     ShadowLayerForwarder::CloseDescriptor(mDescriptor);
   }
 
-  if (mTextureInfo.mTextureFlags & TEXTURE_DEALLOCATE_HOST) {
+  if (!(mTextureInfo.mTextureFlags & TEXTURE_DEALLOCATE_CLIENT)) {
     mDescriptor = SurfaceDescriptor();
     return;
   }
 
   if (IsSurfaceDescriptorValid(mDescriptor)) {
     mForwarder->DestroySharedSurface(&mDescriptor);
     mDescriptor = SurfaceDescriptor();
   }
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -215,23 +215,16 @@ public:
    * anymore. This usually means it will soon be destroyed.
    */
   void MarkInvalid() { mValid = false; }
 
 protected:
   void AddFlags(TextureFlags  aFlags)
   {
     MOZ_ASSERT(!IsSharedWithCompositor());
-    // make sure we don't deallocate on both client and host;
-    MOZ_ASSERT(!(aFlags & TEXTURE_DEALLOCATE_CLIENT && aFlags & TEXTURE_DEALLOCATE_HOST));
-    if (aFlags & TEXTURE_DEALLOCATE_CLIENT) {
-      mFlags &= ~TEXTURE_DEALLOCATE_HOST;
-    } else if (aFlags & TEXTURE_DEALLOCATE_HOST) {
-      mFlags &= ~TEXTURE_DEALLOCATE_CLIENT;
-    }
     mFlags |= aFlags;
   }
 
   uint64_t mID;
   TextureFlags mFlags;
   bool mShared;
   bool mValid;
 };
--- a/gfx/layers/composite/CompositableHost.cpp
+++ b/gfx/layers/composite/CompositableHost.cpp
@@ -34,17 +34,17 @@ CompositableHost::CompositableHost(const
 }
 
 CompositableHost::~CompositableHost()
 {
   MOZ_COUNT_DTOR(CompositableHost);
 
   RefPtr<TextureHost> it = mFirstTexture;
   while (it) {
-    if (it->GetFlags() & TEXTURE_DEALLOCATE_HOST) {
+    if (!(it->GetFlags() & TEXTURE_DEALLOCATE_CLIENT)) {
       it->DeallocateSharedData();
     }
     it = it->GetNextSibling();
   }
 }
 
 void
 CompositableHost::AddTextureHost(TextureHost* aTexture)
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp
+++ b/gfx/layers/ipc/CompositableTransactionParent.cpp
@@ -255,26 +255,26 @@ CompositableParentManager::ReceiveCompos
       }
       CompositableHost* compositable = AsCompositable(op);
 
       RefPtr<TextureHost> texture = compositable->GetTextureHost(op.textureID());
       MOZ_ASSERT(texture);
 
       TextureFlags flags = texture->GetFlags();
 
-      if (flags & TEXTURE_DEALLOCATE_HOST) {
+      if (!(flags & TEXTURE_DEALLOCATE_CLIENT)) {
         texture->DeallocateSharedData();
       }
 
       compositable->RemoveTextureHost(op.textureID());
 
       // if it is not the host that deallocates the shared data, then we need
       // to notfy the client side to tell when it is safe to deallocate or
       // reuse it.
-      if (!(flags & TEXTURE_DEALLOCATE_HOST)) {
+      if (flags & TEXTURE_DEALLOCATE_CLIENT) {
         replyv.push_back(ReplyTextureRemoved(op.compositableParent(), nullptr,
                                              op.textureID()));
       }
 
       break;
     }
     case CompositableOperation::TOpUpdateTexture: {
       const OpUpdateTexture& op = aEdit.get_OpUpdateTexture();
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -117,26 +117,26 @@ ImageBridgeChild::AddTexture(Compositabl
                              aTexture->GetFlags()));
 }
 
 void
 ImageBridgeChild::RemoveTexture(CompositableClient* aCompositable,
                                 uint64_t aTexture,
                                 TextureFlags aFlags)
 {
-  if (aFlags & TEXTURE_DEALLOCATE_HOST) {
-    // if deallocation happens on the host side, we don't need the transaction
+  if (aFlags & TEXTURE_DEALLOCATE_CLIENT) {
+    // if deallocation happens on the host side, we need the transaction
     // to be synchronous.
+    mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
+                                  aTexture,
+                                  aFlags));
+  } else {
     mTxn->AddNoSwapEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
                                         aTexture,
                                         aFlags));
-  } else {
-    mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
-                                  aTexture,
-                                  aFlags));
   }
 }
 
 void
 ImageBridgeChild::UseTexture(CompositableClient* aCompositable,
                              TextureClient* aTexture)
 {
   mTxn->AddNoSwapEdit(OpUseTexture(nullptr, aCompositable->GetIPDLActor(),
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -406,17 +406,17 @@ ShadowLayerForwarder::AddTexture(Composi
 void
 ShadowLayerForwarder::RemoveTexture(CompositableClient* aCompositable,
                                     uint64_t aTexture,
                                     TextureFlags aFlags)
 {
   mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(),
                                 aTexture,
                                 aFlags));
-  if (!(aFlags & TEXTURE_DEALLOCATE_HOST)) {
+  if (aFlags & TEXTURE_DEALLOCATE_CLIENT) {
     mTxn->MarkSyncTransaction();
   }
 }
 
 void
 ShadowLayerForwarder::UpdatedTexture(CompositableClient* aCompositable,
                                      TextureClient* aTexture,
                                      nsIntRegion* aRegion)
--- a/gfx/layers/opengl/TextureClientOGL.cpp
+++ b/gfx/layers/opengl/TextureClientOGL.cpp
@@ -16,23 +16,23 @@ namespace layers {
 
 class CompositableForwarder;
 
 SharedTextureClientOGL::SharedTextureClientOGL(TextureFlags aFlags)
   : TextureClient(aFlags)
   , mHandle(0)
   , mInverted(false)
 {
-  MOZ_ASSERT(!(aFlags & (TEXTURE_DEALLOCATE_CLIENT|TEXTURE_DEALLOCATE_HOST)),
-             "SharedTextureClientOGL doesn't know how to release textures!");
+  // SharedTextureClient is always owned externally.
+  mFlags |= TEXTURE_DEALLOCATE_CLIENT;
 }
 
 SharedTextureClientOGL::~SharedTextureClientOGL()
 {
-  // the data is owned externally.
+  // the shared data is owned externally.
 }
 
 
 bool
 SharedTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
   MOZ_ASSERT(IsValid());
   if (!IsAllocated()) {