Bug 1131638 - Discard video frames that fail to sync. r=cpearce, a=lmandel
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 12 Mar 2015 22:13:23 +1300
changeset 250405 297e2e626fe9
parent 250404 bb7b546e6188
child 250406 f88fcb8ccc27
push id4577
push usermwoodrow@mozilla.com
push date2015-03-17 01:11 +0000
treeherdermozilla-beta@edb24ca59d13 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, lmandel
bugs1131638
milestone37.0
Bug 1131638 - Discard video frames that fail to sync. r=cpearce, a=lmandel
gfx/layers/D3D9SurfaceImage.cpp
gfx/layers/D3D9SurfaceImage.h
gfx/layers/ImageContainer.h
gfx/layers/client/ImageClient.cpp
--- a/gfx/layers/D3D9SurfaceImage.cpp
+++ b/gfx/layers/D3D9SurfaceImage.cpp
@@ -12,16 +12,17 @@
 
 namespace mozilla {
 namespace layers {
 
 
 D3D9SurfaceImage::D3D9SurfaceImage()
   : Image(nullptr, ImageFormat::D3D9_RGB32_TEXTURE)
   , mSize(0, 0)
+  , mValid(false)
 {}
 
 D3D9SurfaceImage::~D3D9SurfaceImage()
 {
   if (mTexture) {
     gfxWindowsPlatform::sD3D9SurfaceImageUsed -= mSize.width * mSize.height * 4;
   }
 }
@@ -148,28 +149,43 @@ D3D9SurfaceImage::SetData(const Data& aD
   mTexture = texture;
   mShareHandle = shareHandle;
   mSize = gfx::IntSize(region.width, region.height);
   mQuery = query;
 
   return S_OK;
 }
 
+bool
+D3D9SurfaceImage::IsValid()
+{
+  EnsureSynchronized();
+  return mValid;
+}
+
 void
 D3D9SurfaceImage::EnsureSynchronized()
 {
   RefPtr<IDirect3DQuery9> query = mQuery;
   if (!query) {
     // Not setup, or already synchronized.
     return;
   }
   int iterations = 0;
-  while (iterations < 10 && S_FALSE == query->GetData(nullptr, 0, D3DGETDATA_FLUSH)) {
-    Sleep(1);
-    iterations++;
+  while (iterations < 10) {
+    HRESULT hr = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
+    if (hr == S_FALSE) {
+      Sleep(1);
+      iterations++;
+      continue;
+    }
+    if (hr == S_OK) {
+      mValid = true;
+    }
+    break;
   }
   mQuery = nullptr;
 }
 
 HANDLE
 D3D9SurfaceImage::GetShareHandle()
 {
   // Ensure the image has completed its synchronization,
--- a/gfx/layers/D3D9SurfaceImage.h
+++ b/gfx/layers/D3D9SurfaceImage.h
@@ -61,14 +61,15 @@ private:
   void EnsureSynchronized();
 
   gfx::IntSize mSize;
   RefPtr<IDirect3DTexture9> mTexture;
   RefPtr<IDirect3DQuery9> mQuery;
   RefPtr<TextureClient> mTextureClient;
   HANDLE mShareHandle;
   D3DSURFACE_DESC mDesc;
+  bool mValid;
 };
 
 } // namepace layers
 } // namespace mozilla
 
 #endif // GFX_D3DSURFACEIMAGE_H
--- a/gfx/layers/ImageContainer.h
+++ b/gfx/layers/ImageContainer.h
@@ -168,16 +168,18 @@ public:
 
   virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() = 0;
 
   virtual GrallocImage* AsGrallocImage()
   {
     return nullptr;
   }
 
+  virtual bool IsValid() { return true; }
+
 protected:
   Image(void* aImplData, ImageFormat aFormat) :
     mImplData(aImplData),
     mSerial(++sSerialCounter),
     mFormat(aFormat),
     mSent(false)
   {}
 
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -142,16 +142,23 @@ ImageClientSingle::UpdateImage(ImageCont
 {
   AutoLockImage autoLock(aContainer);
 
   Image *image = autoLock.GetImage();
   if (!image) {
     return false;
   }
 
+  // Don't try to update to an invalid image. We return true because the caller
+  // would attempt to recreate the ImageClient otherwise, and that isn't going
+  // to help.
+  if (!image->IsValid()) {
+    return true;
+  }
+
   if (mLastPaintedImageSerial == image->GetSerial()) {
     return true;
   }
 
   RefPtr<TextureClient> texture = image->AsSharedImage()
                                 ? image->AsSharedImage()->GetTextureClient(this)
                                 : nullptr;