Bug 1478754 - WebGL crash when webgl.enable-surface-texture is enabled on Android; draft
authorImanol Fernandez <mortimergoro@gmail.com>
Sat, 28 Jul 2018 12:33:55 +0200
changeset 823792 188fc6dad074c041269cf14a8ebd222907e347cc
parent 823791 23b0e1c2a9d38cb6eeab83418ee65dac1b38100e
push id117779
push userbmo:imanol@mozilla.com
push dateSat, 28 Jul 2018 10:35:42 +0000
bugs1478754
milestone63.0a1
Bug 1478754 - WebGL crash when webgl.enable-surface-texture is enabled on Android; MozReview-Commit-ID: GBTvZiLspvP
gfx/gl/SharedSurface.h
gfx/gl/SharedSurfaceEGL.cpp
gfx/gl/SharedSurfaceEGL.h
gfx/layers/client/CanvasClient.cpp
--- a/gfx/gl/SharedSurface.h
+++ b/gfx/gl/SharedSurface.h
@@ -127,16 +127,20 @@ public:
         mIsProducerAcquired = false;
     }
 
     // This function waits until the buffer is no longer being used.
     // To optimize the performance, some implementaions recycle SharedSurfaces
     // even when its buffer is still being used.
     virtual void WaitForBufferOwnership() {}
 
+    // Returns true if the buffer is available.
+    // You can call WaitForBufferOwnership to wait for availability.
+    virtual bool IsBufferAvailable() const { return true; }
+
     // For use when AttachType is correct.
     virtual GLenum ProdTextureTarget() const {
         MOZ_ASSERT(mAttachType == AttachmentType::GLTexture);
         return LOCAL_GL_TEXTURE_2D;
     }
 
     virtual GLuint ProdTexture() {
         MOZ_ASSERT(mAttachType == AttachmentType::GLTexture);
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -268,16 +268,21 @@ SharedSurface_SurfaceTexture::Commit()
 void
 SharedSurface_SurfaceTexture::WaitForBufferOwnership()
 {
     MOZ_RELEASE_ASSERT(!mSurface->GetAvailable());
     mSurface->SetAvailable(true);
 }
 
 bool
+SharedSurface_SurfaceTexture::IsBufferAvailable() const {
+    return mSurface->GetAvailable();
+}
+
+bool
 SharedSurface_SurfaceTexture::ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor)
 {
     *out_descriptor =
         layers::SurfaceTextureDescriptor(mSurface->GetHandle(),
                                          mSize,
                                          gfx::SurfaceFormat::R8G8B8A8,
                                          false /* NOT continuous */,
                                          false /* Do not ignore transform */);
--- a/gfx/gl/SharedSurfaceEGL.h
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -169,16 +169,18 @@ public:
     // Returns texture and target
     virtual bool ToSurfaceDescriptor(layers::SurfaceDescriptor* const out_descriptor) override;
 
     virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) override { return false; }
 
     virtual void Commit() override;
 
     virtual void WaitForBufferOwnership() override;
+
+    virtual bool IsBufferAvailable() const override;
 };
 
 
 
 class SurfaceFactory_SurfaceTexture
     : public SurfaceFactory
 {
 public:
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -424,16 +424,21 @@ CanvasClientSharedSurface::UpdateRendere
     gfxCriticalError() << "Invalid canvas front buffer or screen";
     return;
   }
 
   newFront = mShSurfClient;
 
   SharedSurface* surf = mShSurfClient->Surf();
 
+  if (!surf->IsBufferAvailable()) {
+    NS_WARNING("SharedSurface buffer not available, skip update");
+    return;
+  }
+  
   // Readback if needed.
   mReadbackClient = nullptr;
 
   auto forwarder = GetForwarder();
 
   bool needsReadback = (surf->mType == SharedSurfaceType::Basic);
   if (needsReadback) {
     TextureFlags flags = TextureFlags::IMMUTABLE;