Bug 1135935 - Part 3: Allow overriding of allocations for texture client recycling. r=sotaro
authorMatt Woodrow <mwoodrow@mozilla.com>
Mon, 10 Aug 2015 16:04:38 -0400
changeset 257927 62a8922fe05c321523a23efd30fafd2b633456b9
parent 257926 47d0d08c131c0dd508dd71ab9db11f3bf61edd7e
child 257928 1e3f1190f6ed498479062b839c960360ac27f1fb
push id29238
push userryanvm@gmail.com
push dateMon, 17 Aug 2015 13:06:57 +0000
treeherdermozilla-central@a6eeb28458fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1135935
milestone43.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 1135935 - Part 3: Allow overriding of allocations for texture client recycling. r=sotaro
dom/media/webrtc/MediaEngineGonkVideoSource.cpp
gfx/layers/ImageContainer.cpp
gfx/layers/client/TextureClientRecycleAllocator.cpp
gfx/layers/client/TextureClientRecycleAllocator.h
--- a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp
@@ -745,21 +745,21 @@ MediaEngineGonkVideoSource::RotateImage(
     dstHeight = aHeight;
   }
 
   uint32_t half_width = dstWidth / 2;
 
   layers::GrallocImage* videoImage = static_cast<layers::GrallocImage*>(image.get());
   MOZ_ASSERT(mTextureClientAllocator);
   RefPtr<layers::TextureClient> textureClient
-    = mTextureClientAllocator->CreateOrRecycleForDrawing(gfx::SurfaceFormat::YUV,
-                                                         gfx::IntSize(dstWidth, dstHeight),
-                                                         layers::BackendSelector::Content,
-                                                         layers::TextureFlags::DEFAULT,
-                                                         layers::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
+    = mTextureClientAllocator->CreateOrRecycle(gfx::SurfaceFormat::YUV,
+                                               gfx::IntSize(dstWidth, dstHeight),
+                                               layers::BackendSelector::Content,
+                                               layers::TextureFlags::DEFAULT,
+                                               layers::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
   if (textureClient) {
     RefPtr<layers::GrallocTextureClientOGL> grallocTextureClient =
       static_cast<layers::GrallocTextureClientOGL*>(textureClient.get());
 
     android::sp<android::GraphicBuffer> destBuffer = grallocTextureClient->GetGraphicBuffer();
 
     void* destMem = nullptr;
     destBuffer->lock(android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, &destMem);
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -616,20 +616,20 @@ CairoImage::GetTextureClient(Compositabl
 
 // XXX only gonk ensure when TextureClient is recycled,
 // TextureHost is not used by CompositableHost.
 #ifdef MOZ_WIDGET_GONK
   RefPtr<TextureClientRecycleAllocator> recycler =
     aClient->GetTextureClientRecycler();
   if (recycler) {
     textureClient =
-      recycler->CreateOrRecycleForDrawing(surface->GetFormat(),
-                                          surface->GetSize(),
-                                          BackendSelector::Content,
-                                          aClient->GetTextureFlags());
+      recycler->CreateOrRecycle(surface->GetFormat(),
+                                surface->GetSize(),
+                                BackendSelector::Content,
+                                aClient->GetTextureFlags());
   }
 #endif
 
 #endif
   if (!textureClient) {
     // gfx::BackendType::NONE means default to content backend
     textureClient = aClient->CreateTextureClientForDrawing(surface->GetFormat(),
                                                            surface->GetSize(),
--- a/gfx/layers/client/TextureClientRecycleAllocator.cpp
+++ b/gfx/layers/client/TextureClientRecycleAllocator.cpp
@@ -27,18 +27,18 @@ public:
   }
 
   void ClearTextureClient() { mTextureClient = nullptr; }
 protected:
   RefPtr<TextureClient> mTextureClient;
 };
 
 TextureClientRecycleAllocator::TextureClientRecycleAllocator(ISurfaceAllocator *aAllocator)
-  : mMaxPooledSize(kMaxPooledSized)
-  , mSurfaceAllocator(aAllocator)
+  : mSurfaceAllocator(aAllocator)
+  , mMaxPooledSize(kMaxPooledSized)
   , mLock("TextureClientRecycleAllocatorImp.mLock")
 {
 }
 
 TextureClientRecycleAllocator::~TextureClientRecycleAllocator()
 {
   MutexAutoLock lock(mLock);
   while (!mPooledClients.empty()) {
@@ -49,22 +49,21 @@ TextureClientRecycleAllocator::~TextureC
 
 void
 TextureClientRecycleAllocator::SetMaxPoolSize(uint32_t aMax)
 {
   mMaxPooledSize = aMax;
 }
 
 already_AddRefed<TextureClient>
-TextureClientRecycleAllocator::CreateOrRecycleForDrawing(
-                                          gfx::SurfaceFormat aFormat,
-                                          gfx::IntSize aSize,
-                                          BackendSelector aSelector,
-                                          TextureFlags aTextureFlags,
-                                          TextureAllocationFlags aAllocFlags)
+TextureClientRecycleAllocator::CreateOrRecycle(gfx::SurfaceFormat aFormat,
+                                               gfx::IntSize aSize,
+                                               BackendSelector aSelector,
+                                               TextureFlags aTextureFlags,
+                                               TextureAllocationFlags aAllocFlags)
 {
   // TextureAllocationFlags is actually used only by ContentClient.
   // This class does not handle ConteClient's TextureClient allocation.
   MOZ_ASSERT(aAllocFlags == TextureAllocationFlags::ALLOC_DEFAULT ||
              aAllocFlags == TextureAllocationFlags::ALLOC_DISALLOW_BUFFERTEXTURECLIENT);
   MOZ_ASSERT(!(aTextureFlags & TextureFlags::RECYCLE));
   aTextureFlags = aTextureFlags | TextureFlags::RECYCLE; // Set recycle flag
 
@@ -72,34 +71,31 @@ TextureClientRecycleAllocator::CreateOrR
 
   {
     MutexAutoLock lock(mLock);
     if (!mPooledClients.empty()) {
       textureHolder = mPooledClients.top();
       mPooledClients.pop();
       // If a pooled TextureClient is not compatible, release it.
       if (textureHolder->GetTextureClient()->GetFormat() != aFormat ||
-          textureHolder->GetTextureClient()->GetSize() != aSize)
-      {
+          textureHolder->GetTextureClient()->GetSize() != aSize) {
         TextureClientReleaseTask* task = new TextureClientReleaseTask(textureHolder->GetTextureClient());
         textureHolder->ClearTextureClient();
         textureHolder = nullptr;
         // Release TextureClient.
         mSurfaceAllocator->GetMessageLoop()->PostTask(FROM_HERE, task);
       } else {
         textureHolder->GetTextureClient()->RecycleTexture(aTextureFlags);
       }
     }
   }
 
   if (!textureHolder) {
     // Allocate new TextureClient
-    RefPtr<TextureClient> texture;
-    texture = TextureClient::CreateForDrawing(mSurfaceAllocator, aFormat, aSize, aSelector,
-                                              aTextureFlags, aAllocFlags);
+    RefPtr<TextureClient> texture = Allocate(aFormat, aSize, aSelector, aTextureFlags, aAllocFlags);
     if (!texture) {
       return nullptr;
     }
     textureHolder = new TextureClientHolder(texture);
   }
 
   {
     MutexAutoLock lock(mLock);
@@ -107,16 +103,27 @@ TextureClientRecycleAllocator::CreateOrR
     // Register TextureClient
     mInUseClients[textureHolder->GetTextureClient()] = textureHolder;
   }
   textureHolder->GetTextureClient()->SetRecycleCallback(TextureClientRecycleAllocator::RecycleCallback, this);
   RefPtr<TextureClient> client(textureHolder->GetTextureClient());
   return client.forget();
 }
 
+already_AddRefed<TextureClient>
+TextureClientRecycleAllocator::Allocate(gfx::SurfaceFormat aFormat,
+                                        gfx::IntSize aSize,
+                                        BackendSelector aSelector,
+                                        TextureFlags aTextureFlags,
+                                        TextureAllocationFlags aAllocFlags)
+{
+  return TextureClient::CreateForDrawing(mSurfaceAllocator, aFormat, aSize, aSelector,
+                                         aTextureFlags, aAllocFlags);
+}
+
 void
 TextureClientRecycleAllocator::RecycleCallbackImp(TextureClient* aClient)
 {
   RefPtr<TextureClientHolder> textureHolder;
   aClient->ClearRecycleCallback();
   {
     MutexAutoLock lock(mLock);
     if (mInUseClients.find(aClient) != mInUseClients.end()) {
--- a/gfx/layers/client/TextureClientRecycleAllocator.h
+++ b/gfx/layers/client/TextureClientRecycleAllocator.h
@@ -20,45 +20,58 @@ class ISurfaceAllocator;
 class TextureClientHolder;
 
 
 /**
  * TextureClientRecycleAllocator provides TextureClients allocation and
  * recycling capabilities. It expects allocations of same sizes and
  * attributres. If a recycled TextureClient is different from
  * requested one, the recycled one is dropped and new TextureClient is allocated.
+ *
+ * By default this uses TextureClient::CreateForDrawing to allocate new texture
+ * clients.
  */
 class TextureClientRecycleAllocator
 {
-  ~TextureClientRecycleAllocator();
+protected:
+  virtual ~TextureClientRecycleAllocator();
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureClientRecycleAllocator)
 
   explicit TextureClientRecycleAllocator(ISurfaceAllocator* aAllocator);
 
   void SetMaxPoolSize(uint32_t aMax);
 
   // Creates and allocates a TextureClient.
   already_AddRefed<TextureClient>
-  CreateOrRecycleForDrawing(gfx::SurfaceFormat aFormat,
-                            gfx::IntSize aSize,
-                            BackendSelector aSelector,
-                            TextureFlags aTextureFlags,
-                            TextureAllocationFlags flags = ALLOC_DEFAULT);
+  CreateOrRecycle(gfx::SurfaceFormat aFormat,
+                  gfx::IntSize aSize,
+                  BackendSelector aSelector,
+                  TextureFlags aTextureFlags,
+                  TextureAllocationFlags flags = ALLOC_DEFAULT);
+
+protected:
+  virtual already_AddRefed<TextureClient>
+  Allocate(gfx::SurfaceFormat aFormat,
+           gfx::IntSize aSize,
+           BackendSelector aSelector,
+           TextureFlags aTextureFlags,
+           TextureAllocationFlags aAllocFlags);
+
+  RefPtr<ISurfaceAllocator> mSurfaceAllocator;
 
 private:
   void RecycleCallbackImp(TextureClient* aClient);
 
   static void RecycleCallback(TextureClient* aClient, void* aClosure);
 
   static const uint32_t kMaxPooledSized = 2;
+  uint32_t mMaxPooledSize;
 
-  uint32_t mMaxPooledSize;
-  RefPtr<ISurfaceAllocator> mSurfaceAllocator;
   std::map<TextureClient*, RefPtr<TextureClientHolder> > mInUseClients;
 
   // On b2g gonk, std::queue might be a better choice.
   // On ICS, fence wait happens implicitly before drawing.
   // Since JB, fence wait happens explicitly when fetching a client from the pool.
   // stack is good from Graphics cache usage point of view.
   std::stack<RefPtr<TextureClientHolder> > mPooledClients;
   Mutex mLock;