Bug 1428272 - Handle ExternalImage lock failure r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Thu, 11 Jan 2018 21:20:53 +0900
changeset 450579 4a4c7d5443ab787422a97adf517c0cc334d60cfd
parent 450578 32371cb3206a39ed863df230cc7c8b318523ba25
child 450580 7e8d140654574a170c2ddc545462100b546d53dc
push id8528
push userryanvm@gmail.com
push dateFri, 12 Jan 2018 02:17:15 +0000
treeherdermozilla-beta@713625f4b2f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1428272
milestone59.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 1428272 - Handle ExternalImage lock failure r=nical
gfx/webrender_bindings/RenderBufferTextureHost.cpp
gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp
gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
gfx/webrender_bindings/RenderSharedSurfaceTextureHost.cpp
gfx/webrender_bindings/RendererOGL.cpp
gfx/webrender_bindings/WebRenderTypes.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
--- a/gfx/webrender_bindings/RenderBufferTextureHost.cpp
+++ b/gfx/webrender_bindings/RenderBufferTextureHost.cpp
@@ -45,29 +45,29 @@ RenderBufferTextureHost::~RenderBufferTe
 }
 
 wr::WrExternalImage
 RenderBufferTextureHost::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
 {
   if (!mLocked) {
     if (!GetBuffer()) {
       // We hit some problems to get the shmem.
-      return RawDataToWrExternalImage(nullptr, 0);
+      return InvalidToWrExternalImage();
     }
     if (mFormat != gfx::SurfaceFormat::YUV) {
       mSurface = gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
                                                                layers::ImageDataSerializer::GetRGBStride(mDescriptor.get_RGBDescriptor()),
                                                                mSize,
                                                                mFormat);
       if (NS_WARN_IF(!mSurface)) {
-        return RawDataToWrExternalImage(nullptr, 0);
+        return InvalidToWrExternalImage();
       }
       if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mMap))) {
         mSurface = nullptr;
-        return RawDataToWrExternalImage(nullptr, 0);
+        return InvalidToWrExternalImage();
       }
     } else {
       const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
 
       mYSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetYChannel(GetBuffer(), desc),
                                                                 desc.yStride(),
                                                                 desc.ySize(),
                                                                 gfx::SurfaceFormat::A8);
@@ -76,23 +76,23 @@ RenderBufferTextureHost::Lock(uint8_t aC
                                                                  desc.cbCrSize(),
                                                                  gfx::SurfaceFormat::A8);
       mCrSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetCrChannel(GetBuffer(), desc),
                                                                  desc.cbCrStride(),
                                                                  desc.cbCrSize(),
                                                                  gfx::SurfaceFormat::A8);
       if (NS_WARN_IF(!mYSurface || !mCbSurface || !mCrSurface)) {
         mYSurface = mCbSurface = mCrSurface = nullptr;
-        return RawDataToWrExternalImage(nullptr, 0);
+        return InvalidToWrExternalImage();
       }
       if (NS_WARN_IF(!mYSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mYMap) ||
                      !mCbSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCbMap) ||
                      !mCrSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCrMap))) {
         mYSurface = mCbSurface = mCrSurface = nullptr;
-        return RawDataToWrExternalImage(nullptr, 0);
+        return InvalidToWrExternalImage();
       }
     }
     mLocked = true;
   }
 
   RenderBufferData data = GetBufferDataForRender(aChannelIndex);
   return RawDataToWrExternalImage(data.mData, data.mBufferSize);
 }
--- a/gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp
+++ b/gfx/webrender_bindings/RenderD3D11TextureHostOGL.cpp
@@ -154,25 +154,25 @@ RenderDXGITextureHostOGL::Lock(uint8_t a
   if (mGL.get() != aGL) {
     // Release the texture handle in the previous gl context.
     DeleteTextureHandle();
     mGL = aGL;
     mGL->MakeCurrent();
   }
 
   if (!EnsureLockable()) {
-    return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
+    return InvalidToWrExternalImage();
   }
 
   if (!mLocked) {
     if (mKeyedMutex) {
       HRESULT hr = mKeyedMutex->AcquireSync(0, 100);
       if (hr != S_OK) {
         gfxCriticalError() << "RenderDXGITextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
-        return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
+        return InvalidToWrExternalImage();
       }
     }
     mLocked = true;
   }
 
   gfx::IntSize size = GetSize(aChannelIndex);
   return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex), 0, 0,
                                         size.width, size.height);
@@ -337,26 +337,26 @@ RenderDXGIYCbCrTextureHostOGL::Lock(uint
   if (mGL.get() != aGL) {
     // Release the texture handle in the previous gl context.
     DeleteTextureHandle();
     mGL = aGL;
     mGL->MakeCurrent();
   }
 
   if (!EnsureLockable()) {
-    return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
+    return InvalidToWrExternalImage();
   }
 
   if (!mLocked) {
     if (mKeyedMutexs[0]) {
       for (const auto& mutex : mKeyedMutexs) {
         HRESULT hr = mutex->AcquireSync(0, 100);
         if (hr != S_OK) {
           gfxCriticalError() << "RenderDXGIYCbCrTextureHostOGL AcquireSync timeout, hr=" << gfx::hexa(hr);
-          return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
+          return InvalidToWrExternalImage();
         }
       }
     }
     mLocked = true;
   }
 
   gfx::IntSize size = GetSize(aChannelIndex);
   return NativeTextureToWrExternalImage(GetGLHandle(aChannelIndex), 0, 0,
--- a/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
@@ -78,17 +78,17 @@ RenderMacIOSurfaceTextureHostOGL::Lock(u
   if (mGL.get() != aGL) {
     // release the texture handle in the previous gl context
     DeleteTextureHandle();
     mGL = aGL;
     mGL->MakeCurrent();
   }
 
   if (!mSurface || !mGL || !mGL->MakeCurrent()) {
-    return NativeTextureToWrExternalImage(0, 0, 0, 0, 0);
+    return InvalidToWrExternalImage();
   }
 
   if (!mTextureHandles[0]) {
     MOZ_ASSERT(gl::GLContextCGL::Cast(mGL.get())->GetCGLContext());
 
     // The result of GetPlaneCount() is 0 for single plane format, but it will
     // be 2 if the format has 2 planar data.
     CreateTextureForPlane(0, mGL, mSurface, &(mTextureHandles[0]));
--- a/gfx/webrender_bindings/RenderSharedSurfaceTextureHost.cpp
+++ b/gfx/webrender_bindings/RenderSharedSurfaceTextureHost.cpp
@@ -26,17 +26,17 @@ RenderSharedSurfaceTextureHost::~RenderS
 }
 
 wr::WrExternalImage
 RenderSharedSurfaceTextureHost::Lock(uint8_t aChannelIndex, gl::GLContext* aGL)
 {
   if (!mLocked) {
     if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE,
                                   &mMap))) {
-      return RawDataToWrExternalImage(nullptr, 0);
+      return InvalidToWrExternalImage();
     }
     mLocked = true;
   }
 
   return RawDataToWrExternalImage(mMap.mData,
                                   mMap.mStride * mSurface->GetSize().height);
 }
 
--- a/gfx/webrender_bindings/RendererOGL.cpp
+++ b/gfx/webrender_bindings/RendererOGL.cpp
@@ -19,24 +19,31 @@
 namespace mozilla {
 namespace wr {
 
 wr::WrExternalImage LockExternalImage(void* aObj, wr::WrExternalImageId aId, uint8_t aChannelIndex)
 {
   RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
   RenderTextureHost* texture = renderer->GetRenderTexture(aId);
   MOZ_ASSERT(texture);
+  if (!texture) {
+    gfxCriticalNote << "Failed to lock ExternalImage for extId:" << AsUint64(aId);
+    return InvalidToWrExternalImage();
+  }
   return texture->Lock(aChannelIndex, renderer->mGL);
 }
 
 void UnlockExternalImage(void* aObj, wr::WrExternalImageId aId, uint8_t aChannelIndex)
 {
   RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
   RenderTextureHost* texture = renderer->GetRenderTexture(aId);
   MOZ_ASSERT(texture);
+  if (!texture) {
+    return;
+  }
   texture->Unlock();
 }
 
 RendererOGL::RendererOGL(RefPtr<RenderThread>&& aThread,
                          RefPtr<gl::GLContext>&& aGL,
                          RefPtr<widget::CompositorWidget>&& aWidget,
                          wr::WindowId aWindowId,
                          wr::Renderer* aRenderer,
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -551,16 +551,25 @@ static inline wr::WrExternalImage Native
 {
   return wr::WrExternalImage {
     wr::WrExternalImageType::NativeTexture,
     aHandle, u0, v0, u1, v1,
     nullptr, 0
   };
 }
 
+static inline wr::WrExternalImage InvalidToWrExternalImage()
+{
+  return wr::WrExternalImage {
+    wr::WrExternalImageType::Invalid,
+    0, 0, 0, 0, 0,
+    nullptr, 0
+  };
+}
+
 inline wr::ByteSlice RangeToByteSlice(mozilla::Range<uint8_t> aRange) {
   return wr::ByteSlice { aRange.begin().get(), aRange.length() };
 }
 
 inline mozilla::Range<const uint8_t> ByteSliceToRange(wr::ByteSlice aWrSlice) {
   return mozilla::Range<const uint8_t>(aWrSlice.buffer, aWrSlice.len);
 }
 
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -263,18 +263,19 @@ impl Into<WrExternalImageId> for Externa
     fn into(self) -> WrExternalImageId {
         WrExternalImageId(self.0)
     }
 }
 
 #[repr(u32)]
 #[allow(dead_code)]
 enum WrExternalImageType {
+    RawData,
     NativeTexture,
-    RawData,
+    Invalid,
 }
 
 #[repr(C)]
 struct WrExternalImage {
     image_type: WrExternalImageType,
 
     // external texture handle
     handle: u32,
@@ -320,16 +321,25 @@ impl ExternalImageHandler for WrExternal
                 ExternalImage {
                     u0: image.u0,
                     v0: image.v0,
                     u1: image.u1,
                     v1: image.v1,
                     source: ExternalImageSource::RawData(make_slice(image.buff, image.size)),
                 }
             },
+            WrExternalImageType::Invalid => {
+                ExternalImage {
+                    u0: image.u0,
+                    v0: image.v0,
+                    u1: image.u1,
+                    v1: image.v1,
+                    source: ExternalImageSource::Invalid,
+                }
+            },
         }
     }
 
     fn unlock(&mut self,
               id: ExternalImageId,
               channel_index: u8) {
         (self.unlock_func)(self.external_image_obj, id.into(), channel_index);
     }
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -201,18 +201,19 @@ enum class TransformStyle : uint32_t {
 enum class WrAnimationType : uint32_t {
   Transform = 0,
   Opacity = 1,
 
   Sentinel /* this must be last for serialization purposes. */
 };
 
 enum class WrExternalImageType : uint32_t {
-  NativeTexture = 0,
-  RawData = 1,
+  RawData = 0,
+  NativeTexture = 1,
+  Invalid = 2,
 
   Sentinel /* this must be last for serialization purposes. */
 };
 
 enum class WrFilterOpType : uint32_t {
   Blur = 0,
   Brightness = 1,
   Contrast = 2,