Bug 982128 - Check that shmem based locks are allocated properly. r=cwiiis
authorNicolas Silva <nical@mozilla.com>
Wed, 12 Mar 2014 17:09:37 +0100
changeset 191412 f6ceb09baa53413211e888f7d42db8961efd6f24
parent 191411 2244835a4adec34b7e0d5dae8b6453340d51e968
child 191413 31844306c2f1e38c4b057dd6b84866d9ca53f3ae
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscwiiis
bugs982128
milestone30.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 982128 - Check that shmem based locks are allocated properly. r=cwiiis
gfx/layers/client/TiledContentClient.cpp
gfx/layers/client/TiledContentClient.h
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -305,57 +305,66 @@ int32_t
 gfxMemorySharedReadLock::GetReadCount()
 {
   NS_ASSERT_OWNINGTHREAD(gfxMemorySharedReadLock);
   return mReadCount;
 }
 
 gfxShmSharedReadLock::gfxShmSharedReadLock(ISurfaceAllocator* aAllocator)
   : mAllocator(aAllocator)
+  , mAllocSuccess(false)
 {
   MOZ_COUNT_CTOR(gfxShmSharedReadLock);
-
+  MOZ_ASSERT(mAllocator);
   if (mAllocator) {
 #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
     if (mAllocator->AllocUnsafeShmem(MOZ_ALIGN_WORD(sizeof(ShmReadLockInfo)),
                                      mozilla::ipc::SharedMemory::TYPE_BASIC, &mShmem)) {
       ShmReadLockInfo* info = GetShmReadLockInfoPtr();
       info->readCount = 1;
+      mAllocSuccess = true;
     }
   }
 }
 
 gfxShmSharedReadLock::~gfxShmSharedReadLock()
 {
   MOZ_COUNT_DTOR(gfxShmSharedReadLock);
 }
 
 int32_t
 gfxShmSharedReadLock::ReadLock() {
   NS_ASSERT_OWNINGTHREAD(gfxShmSharedReadLock);
-
+  if (!mAllocSuccess) {
+    return 0;
+  }
   ShmReadLockInfo* info = GetShmReadLockInfoPtr();
   return PR_ATOMIC_INCREMENT(&info->readCount);
 }
 
 int32_t
 gfxShmSharedReadLock::ReadUnlock() {
+  if (!mAllocSuccess) {
+    return 0;
+  }
   ShmReadLockInfo* info = GetShmReadLockInfoPtr();
   int32_t readCount = PR_ATOMIC_DECREMENT(&info->readCount);
   NS_ASSERTION(readCount >= 0, "ReadUnlock called without a ReadLock.");
   if (readCount <= 0) {
     mAllocator->DeallocShmem(mShmem);
   }
   return readCount;
 }
 
 int32_t
 gfxShmSharedReadLock::GetReadCount() {
   NS_ASSERT_OWNINGTHREAD(gfxShmSharedReadLock);
-
+  if (!mAllocSuccess) {
+    return 0;
+  }
   ShmReadLockInfo* info = GetShmReadLockInfoPtr();
   return info->readCount;
 }
 
 // Placeholder
 TileClient::TileClient()
   : mBackBuffer(nullptr)
   , mFrontBuffer(nullptr)
@@ -509,16 +518,19 @@ TileClient::GetBackBuffer(const nsIntReg
     // Create a lock for our newly created back-buffer.
     if (gfxPlatform::GetPlatform()->PreferMemoryOverShmem()) {
       // If our compositor is in the same process, we can save some cycles by not
       // using shared memory.
       mBackLock = new gfxMemorySharedReadLock();
     } else {
       mBackLock = new gfxShmSharedReadLock(mManager->AsShadowForwarder());
     }
+
+    MOZ_ASSERT(mBackLock->IsValid());
+
     *aCreatedTextureClient = true;
     mInvalidBack = nsIntRect(0, 0, TILEDLAYERBUFFER_TILE_SIZE, TILEDLAYERBUFFER_TILE_SIZE);
   }
 
   ValidateBackBufferFromFront(aDirtyRegion, aCanRerasterizeValidRegion);
 
   return mBackBuffer;
 }
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -50,16 +50,17 @@ class ClientLayerManager;
 class gfxSharedReadLock : public AtomicRefCounted<gfxSharedReadLock> {
 public:
   MOZ_DECLARE_REFCOUNTED_TYPENAME(gfxSharedReadLock)
   virtual ~gfxSharedReadLock() {}
 
   virtual int32_t ReadLock() = 0;
   virtual int32_t ReadUnlock() = 0;
   virtual int32_t GetReadCount() = 0;
+  virtual bool IsValid() const = 0;
 
   enum gfxSharedReadLockType {
     TYPE_MEMORY,
     TYPE_SHMEM
   };
   virtual gfxSharedReadLockType GetType() = 0;
 
 protected:
@@ -75,16 +76,18 @@ public:
   virtual int32_t ReadLock() MOZ_OVERRIDE;
 
   virtual int32_t ReadUnlock() MOZ_OVERRIDE;
 
   virtual int32_t GetReadCount() MOZ_OVERRIDE;
 
   virtual gfxSharedReadLockType GetType() MOZ_OVERRIDE { return TYPE_MEMORY; }
 
+  virtual bool IsValid() const MOZ_OVERRIDE { return true; };
+
 private:
   int32_t mReadCount;
 };
 
 class gfxShmSharedReadLock : public gfxSharedReadLock {
 private:
   struct ShmReadLockInfo {
     int32_t readCount;
@@ -96,43 +99,47 @@ public:
   ~gfxShmSharedReadLock();
 
   virtual int32_t ReadLock() MOZ_OVERRIDE;
 
   virtual int32_t ReadUnlock() MOZ_OVERRIDE;
 
   virtual int32_t GetReadCount() MOZ_OVERRIDE;
 
+  virtual bool IsValid() const MOZ_OVERRIDE { return mAllocSuccess; };
+
   virtual gfxSharedReadLockType GetType() MOZ_OVERRIDE { return TYPE_SHMEM; }
 
   mozilla::ipc::Shmem& GetShmem() { return mShmem; }
 
   static already_AddRefed<gfxShmSharedReadLock>
   Open(mozilla::layers::ISurfaceAllocator* aAllocator, const mozilla::ipc::Shmem& aShmem)
   {
     nsRefPtr<gfxShmSharedReadLock> readLock = new gfxShmSharedReadLock(aAllocator, aShmem);
     return readLock.forget();
   }
 
 private:
   gfxShmSharedReadLock(ISurfaceAllocator* aAllocator, const mozilla::ipc::Shmem& aShmem)
     : mAllocator(aAllocator)
     , mShmem(aShmem)
+    , mAllocSuccess(true)
   {
     MOZ_COUNT_CTOR(gfxShmSharedReadLock);
   }
 
   ShmReadLockInfo* GetShmReadLockInfoPtr()
   {
     return reinterpret_cast<ShmReadLockInfo*>
       (mShmem.get<char>() + mShmem.Size<char>() - sizeof(ShmReadLockInfo));
   }
 
   RefPtr<ISurfaceAllocator> mAllocator;
   mozilla::ipc::Shmem mShmem;
+  bool mAllocSuccess;
 };
 
 /**
  * Represent a single tile in tiled buffer. The buffer keeps tiles,
  * each tile keeps a reference to a texture client and a read-lock. This
  * read-lock is used to help implement a copy-on-write mechanism. The tile
  * should be locked before being sent to the compositor. The compositor should
  * unlock the read-lock as soon as it has finished with the buffer in the
@@ -165,24 +172,28 @@ struct TileClient
 
   bool IsPlaceholderTile()
   {
     return mBackBuffer == nullptr && mFrontBuffer == nullptr;
   }
 
   void ReadUnlock()
   {
-    NS_ASSERTION(mFrontLock != nullptr, "ReadUnlock with no gfxSharedReadLock");
-    mFrontLock->ReadUnlock();
+    MOZ_ASSERT(mFrontLock, "ReadLock with no gfxSharedReadLock");
+    if (mFrontLock) {
+      mFrontLock->ReadUnlock();
+    }
   }
 
   void ReadLock()
   {
-    NS_ASSERTION(mFrontLock != nullptr, "ReadLock with no gfxSharedReadLock");
-    mFrontLock->ReadLock();
+    MOZ_ASSERT(mFrontLock, "ReadLock with no gfxSharedReadLock");
+    if (mFrontLock) {
+      mFrontLock->ReadLock();
+    }
   }
 
   void Release()
   {
     DiscardFrontBuffer();
     DiscardBackBuffer();
   }