Bug 1027601 - Create and Allocate TextureClients in a single step in SharedPlanarYCbCrImage. r=sotaro
authorNicolas Silva <nsilva@mozilla.com>
Thu, 10 Jul 2014 13:48:29 +0200
changeset 193380 31c5ac29e510f31668466af51e78204c2317fee1
parent 193379 1dacd89b4ce487403f587944b1609511c1c6f783
child 193381 0a1ce8ffbf1cc30b43a307e8b8636d4d37dbe3d0
push id27117
push userryanvm@gmail.com
push dateThu, 10 Jul 2014 22:23:14 +0000
treeherdermozilla-central@e1a037c085d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1027601
milestone33.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 1027601 - Create and Allocate TextureClients in a single step in SharedPlanarYCbCrImage. r=sotaro
gfx/layers/client/CompositableClient.h
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -221,16 +221,18 @@ public:
   void InitIPDLActor(PCompositableChild* aActor, uint64_t aAsyncID = 0);
 
   static void TransactionCompleteted(PCompositableChild* aActor, uint64_t aTransactionId);
 
   static void HoldUntilComplete(PCompositableChild* aActor, AsyncTransactionTracker* aTracker);
 
   static uint64_t GetTrackersHolderId(PCompositableChild* aActor);
 
+  TextureFlags GetTextureFlags() const { return mTextureFlags; }
+
 protected:
   CompositableChild* mCompositableChild;
   CompositableForwarder* mForwarder;
   // Some layers may want to enforce some flags to all their textures
   // (like disallowing tiling)
   TextureFlags mTextureFlags;
 
   friend class CompositableChild;
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -360,16 +360,43 @@ TextureClient::CreateForRawBufferAccess(
       return nullptr;
     }
   }
   return texture;
 }
 
 // static
 TemporaryRef<BufferTextureClient>
+TextureClient::CreateForYCbCr(ISurfaceAllocator* aAllocator,
+                              gfx::IntSize aYSize,
+                              gfx::IntSize aCbCrSize,
+                              StereoMode aStereoMode,
+                              TextureFlags aTextureFlags)
+{
+  RefPtr<BufferTextureClient> texture;
+  if (aAllocator->IsSameProcess()) {
+    texture = new MemoryTextureClient(aAllocator, gfx::SurfaceFormat::YUV,
+                                      gfx::BackendType::NONE,
+                                      aTextureFlags);
+  } else {
+    texture = new ShmemTextureClient(aAllocator, gfx::SurfaceFormat::YUV,
+                                     gfx::BackendType::NONE,
+                                     aTextureFlags);
+  }
+
+  if (!texture->AllocateForYCbCr(aYSize, aCbCrSize, aStereoMode)) {
+    return nullptr;
+  }
+
+  return texture;
+}
+
+
+// static
+TemporaryRef<BufferTextureClient>
 TextureClient::CreateBufferTextureClient(ISurfaceAllocator* aAllocator,
                                          SurfaceFormat aFormat,
                                          TextureFlags aTextureFlags,
                                          gfx::BackendType aMoz2DBackend)
 {
   if (aAllocator->IsSameProcess()) {
     RefPtr<BufferTextureClient> result = new MemoryTextureClient(aAllocator, aFormat,
                                                                  aMoz2DBackend,
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -134,16 +134,24 @@ public:
   static TemporaryRef<TextureClient>
   CreateForDrawing(ISurfaceAllocator* aAllocator,
                    gfx::SurfaceFormat aFormat,
                    gfx::IntSize aSize,
                    gfx::BackendType aMoz2dBackend,
                    TextureFlags aTextureFlags,
                    TextureAllocationFlags flags = ALLOC_DEFAULT);
 
+  // Creates and allocates a BufferTextureClient supporting the YCbCr format.
+  static TemporaryRef<BufferTextureClient>
+  CreateForYCbCr(ISurfaceAllocator* aAllocator,
+                 gfx::IntSize aYSize,
+                 gfx::IntSize aCbCrSize,
+                 StereoMode aStereoMode,
+                 TextureFlags aTextureFlags);
+
   // Creates and allocates a BufferTextureClient (can beaccessed through raw
   // pointers).
   static TemporaryRef<BufferTextureClient>
   CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
                            gfx::SurfaceFormat aFormat,
                            gfx::IntSize aSize,
                            gfx::BackendType aMoz2dBackend,
                            TextureFlags aTextureFlags,
--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
@@ -24,17 +24,16 @@ namespace mozilla {
 namespace layers {
 
 using namespace mozilla::ipc;
 
 SharedPlanarYCbCrImage::SharedPlanarYCbCrImage(ImageClient* aCompositable)
 : PlanarYCbCrImage(nullptr)
 , mCompositable(aCompositable)
 {
-  mTextureClient = aCompositable->CreateBufferTextureClient(gfx::SurfaceFormat::YUV);
   MOZ_COUNT_CTOR(SharedPlanarYCbCrImage);
 }
 
 SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
   MOZ_COUNT_DTOR(SharedPlanarYCbCrImage);
 
   if (mCompositable->GetAsyncID() != 0 &&
       !InImageBridgeChildThread()) {
@@ -64,84 +63,73 @@ uint8_t*
 SharedPlanarYCbCrImage::GetBuffer()
 {
   return mTextureClient->GetBuffer();
 }
 
 TemporaryRef<gfx::SourceSurface>
 SharedPlanarYCbCrImage::GetAsSourceSurface()
 {
-  if (!mTextureClient->IsAllocated()) {
+  if (!mTextureClient) {
     NS_WARNING("Can't get as surface");
     return nullptr;
   }
   return PlanarYCbCrImage::GetAsSourceSurface();
 }
 
 void
 SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
 {
-  // If mShmem has not been allocated (through Allocate(aData)), allocate it.
-  // This code path is slower than the one used when Allocate has been called
-  // since it will trigger a full copy.
-  if (!mTextureClient->IsAllocated()) {
-    Data data = aData;
-    if (!Allocate(data)) {
-      NS_WARNING("SharedPlanarYCbCrImage::SetData failed to allocate");
-      return;
-    }
+  // If mTextureClient has not already been allocated (through Allocate(aData))
+  // allocate it. This code path is slower than the one used when Allocate has
+  // been called since it will trigger a full copy.
+  PlanarYCbCrData data = aData;
+  if (!mTextureClient && !Allocate(data)) {
+    return;
   }
 
   MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr());
   if (!mTextureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) {
     MOZ_ASSERT(false, "Failed to lock the texture.");
     return;
   }
   TextureClientAutoUnlock unlock(mTextureClient);
   if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) {
     MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
     return;
   }
-  // do not set mBuffer like in PlanarYCbCrImage because the later
-  // will try to manage this memory without knowing it belongs to a
-  // shmem.
-  mBufferSize = YCbCrImageDataSerializer::ComputeMinBufferSize(mData.mYSize,
-                                                               mData.mCbCrSize);
-  mSize = mData.mPicSize;
-
-  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
-  mData.mYChannel = serializer.GetYData();
-  mData.mCbChannel = serializer.GetCbData();
-  mData.mCrChannel = serializer.GetCrData();
   mTextureClient->MarkImmutable();
 }
 
 // needs to be overriden because the parent class sets mBuffer which we
 // do not want to happen.
 uint8_t*
 SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
 {
-  NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(), "This image already has allocated data");
+  NS_ABORT_IF_FALSE(!mTextureClient, "This image already has allocated data");
   size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aSize);
 
+  mTextureClient = mCompositable->CreateBufferTextureClient(gfx::SurfaceFormat::YUV);
   // get new buffer _without_ setting mBuffer.
   if (!mTextureClient->Allocate(size)) {
+    mTextureClient = nullptr;
     return nullptr;
   }
 
   // update buffer size
   mBufferSize = size;
 
   YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   return serializer.GetData();
 }
 
 void
 SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
 {
+  NS_ABORT_IF_FALSE(mTextureClient, "This Image should have already allocated data");
   mData = aData;
   mSize = aData.mPicSize;
   /* SetDataNoCopy is used to update YUV plane offsets without (re)allocating
    * memory previously allocated with AllocateAndGetNewBuffer().
    * serializer.GetData() returns the address of the memory previously allocated
    * with AllocateAndGetNewBuffer(), that we subtract from the Y, Cb, Cr
    * channels to compute 0-based offsets to pass to InitializeBufferInfo.
    */
@@ -158,39 +146,43 @@ SharedPlanarYCbCrImage::SetDataNoCopy(co
                                   aData.mYSize,
                                   aData.mCbCrSize,
                                   aData.mStereoMode);
 }
 
 uint8_t*
 SharedPlanarYCbCrImage::AllocateBuffer(uint32_t aSize)
 {
-  NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(),
+  NS_ABORT_IF_FALSE(!mTextureClient,
                     "This image already has allocated data");
+  mTextureClient = mCompositable->CreateBufferTextureClient(gfx::SurfaceFormat::YUV);
   if (!mTextureClient->Allocate(aSize)) {
+    mTextureClient = nullptr;
     return nullptr;
   }
   return mTextureClient->GetBuffer();
 }
 
 bool
 SharedPlanarYCbCrImage::IsValid() {
-  return mTextureClient->IsAllocated();
+  return !!mTextureClient;
 }
 
 bool
 SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
 {
-  NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(),
+  NS_ABORT_IF_FALSE(!mTextureClient,
                     "This image already has allocated data");
 
-  size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aData.mYSize,
-                                                               aData.mCbCrSize);
-
-  if (AllocateBuffer(static_cast<uint32_t>(size)) == nullptr) {
+  mTextureClient = TextureClient::CreateForYCbCr(mCompositable->GetForwarder(),
+                                                 aData.mYSize, aData.mCbCrSize,
+                                                 aData.mStereoMode,
+                                                 mCompositable->GetTextureFlags());
+  if (!mTextureClient) {
+    NS_WARNING("SharedPlanarYCbCrImage::Allocate failed.");
     return false;
   }
 
   YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   serializer.InitializeBufferInfo(aData.mYSize,
                                   aData.mCbCrSize,
                                   aData.mStereoMode);
   MOZ_ASSERT(serializer.IsValid());
@@ -212,13 +204,20 @@ SharedPlanarYCbCrImage::Allocate(PlanarY
   // those members are not always equal to aData's, due to potentially different
   // packing.
   mData.mYSkip = 0;
   mData.mCbSkip = 0;
   mData.mCrSkip = 0;
   mData.mYStride = mData.mYSize.width;
   mData.mCbCrStride = mData.mCbCrSize.width;
 
+  // do not set mBuffer like in PlanarYCbCrImage because the later
+  // will try to manage this memory without knowing it belongs to a
+  // shmem.
+  mBufferSize = YCbCrImageDataSerializer::ComputeMinBufferSize(mData.mYSize,
+                                                               mData.mCbCrSize);
+  mSize = mData.mPicSize;
+
   return true;
 }
 
 } // namespace
 } // namespace