Bug 716190 - Retry graphic buffer locks if we get -EBUSY r=pcwalton
authorJames Willcox <jwillcox@mozilla.com>
Tue, 17 Jan 2012 15:00:56 -0500
changeset 85976 6da5a83a4a5c18dbaedf9bb2518020dc0e60c9b7
parent 85975 b8ede0b17a1c05aa58298d409c5f6a2bf986ae08
child 85977 d27ddb7ad0322f1a2bb866092532bd2f3b764e40
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspcwalton
bugs716190
milestone12.0a1
Bug 716190 - Retry graphic buffer locks if we get -EBUSY r=pcwalton
widget/android/AndroidDirectTexture.cpp
widget/android/AndroidGraphicBuffer.cpp
widget/android/AndroidGraphicBuffer.h
widget/android/nsWindow.cpp
--- a/widget/android/AndroidDirectTexture.cpp
+++ b/widget/android/AndroidDirectTexture.cpp
@@ -30,16 +30,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include <unistd.h>
+#include <errno.h>
 #include "AndroidDirectTexture.h"
 
 typedef gfxASurface::gfxImageFormat gfxImageFormat;
 
 namespace mozilla {
 
 AndroidDirectTexture::AndroidDirectTexture(PRUint32 width, PRUint32 height, PRUint32 usage,
                                            gfxImageFormat format) :
@@ -79,27 +81,32 @@ AndroidDirectTexture::ReallocPendingBuff
     mBackBuffer->Reallocate(mWidth, mHeight, mFormat);
     mPendingReallocBuffer = NULL;
   }
 }
 
 bool
 AndroidDirectTexture::Lock(PRUint32 aUsage, unsigned char **bits)
 {
-  mLock.Lock();
-  ReallocPendingBuffer();
-  return mBackBuffer->Lock(aUsage, bits);
+  nsIntRect rect(0, 0, mWidth, mHeight);
+  return Lock(aUsage, rect, bits);
 }
 
 bool
 AndroidDirectTexture::Lock(PRUint32 aUsage, const nsIntRect& aRect, unsigned char **bits)
 {
   mLock.Lock();
   ReallocPendingBuffer();
-  return mBackBuffer->Lock(aUsage, aRect, bits);
+
+  int result;
+  while ((result = mBackBuffer->Lock(aUsage, aRect, bits)) == -EBUSY) {
+    usleep(1000); // 1ms
+  }
+
+  return result == 0;
 }
 
 bool
 AndroidDirectTexture::Unlock(bool aFlip)
 {
   if (aFlip) {
     mNeedFlip = true;
   }
--- a/widget/android/AndroidGraphicBuffer.cpp
+++ b/widget/android/AndroidGraphicBuffer.cpp
@@ -319,47 +319,47 @@ AndroidGraphicBuffer::EnsureInitialized(
   if (!sGLFunctions.EnsureInitialized()) {
     return false;
   }
 
   EnsureBufferCreated();
   return true;
 }
 
-bool
+int
 AndroidGraphicBuffer::Lock(PRUint32 aUsage, unsigned char **bits)
 {
   if (!EnsureInitialized())
     return true;
 
-  return sGLFunctions.fGraphicBufferLock(mHandle, GetAndroidUsage(aUsage), bits) == 0;
+  return sGLFunctions.fGraphicBufferLock(mHandle, GetAndroidUsage(aUsage), bits);
 }
 
-bool
+int
 AndroidGraphicBuffer::Lock(PRUint32 aUsage, const nsIntRect& aRect, unsigned char **bits)
 {
   if (!EnsureInitialized())
     return false;
 
   AndroidRect rect;
   rect.left = aRect.x;
   rect.top = aRect.y;
   rect.right = aRect.x + aRect.width;
   rect.bottom = aRect.y + aRect.height;
 
-  return sGLFunctions.fGraphicBufferLockRect(mHandle, GetAndroidUsage(aUsage), rect, bits) == 0;
+  return sGLFunctions.fGraphicBufferLockRect(mHandle, GetAndroidUsage(aUsage), rect, bits);
 }
 
-bool
+int
 AndroidGraphicBuffer::Unlock()
 {
   if (!EnsureInitialized())
     return false;
 
-  return sGLFunctions.fGraphicBufferUnlock(mHandle) == 0;
+  return sGLFunctions.fGraphicBufferUnlock(mHandle);
 }
 
 bool
 AndroidGraphicBuffer::Reallocate(PRUint32 aWidth, PRUint32 aHeight, gfxImageFormat aFormat)
 {
   if (!EnsureInitialized())
     return false;
 
--- a/widget/android/AndroidGraphicBuffer.h
+++ b/widget/android/AndroidGraphicBuffer.h
@@ -61,19 +61,19 @@ public:
     UsageTexture = 1 << 2,
     UsageTarget = 1 << 3,
     Usage2D = 1 << 4
   };
 
   AndroidGraphicBuffer(PRUint32 width, PRUint32 height, PRUint32 usage, gfxASurface::gfxImageFormat format);
   virtual ~AndroidGraphicBuffer();
 
-  bool Lock(PRUint32 usage, unsigned char **bits);
-  bool Lock(PRUint32 usage, const nsIntRect& rect, unsigned char **bits);
-  bool Unlock();
+  int Lock(PRUint32 usage, unsigned char **bits);
+  int Lock(PRUint32 usage, const nsIntRect& rect, unsigned char **bits);
+  int Unlock();
   bool Reallocate(PRUint32 aWidth, PRUint32 aHeight, gfxASurface::gfxImageFormat aFormat);
 
   PRUint32 Width() { return mWidth; }
   PRUint32 Height() { return mHeight; }
 
   bool Bind();
 
 private:
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -832,24 +832,24 @@ nsWindow::HasDirectTexture()
   if (!sHasDirectTexture)
     return false;
 
   AndroidGraphicBuffer* buffer = new AndroidGraphicBuffer(512, 512,
       AndroidGraphicBuffer::UsageSoftwareWrite | AndroidGraphicBuffer::UsageTexture,
       gfxASurface::ImageFormatRGB16_565);
 
   unsigned char* bits = NULL;
-  if (!buffer->Lock(AndroidGraphicBuffer::UsageSoftwareWrite, &bits) || !bits) {
+  if (buffer->Lock(AndroidGraphicBuffer::UsageSoftwareWrite, &bits) != 0 || !bits) {
     ALOG("failed to lock graphic buffer");
     buffer->Unlock();
     sHasDirectTexture = false;
     goto cleanup;
   }
 
-  if (!buffer->Unlock()) {
+  if (buffer->Unlock() != 0) {
     ALOG("failed to unlock graphic buffer");
     sHasDirectTexture = false;
     goto cleanup;
   }
 
   if (!buffer->Reallocate(1024, 1024, gfxASurface::ImageFormatRGB16_565)) {
     ALOG("failed to reallocate graphic buffer");
     sHasDirectTexture = false;