Bug 1045955 - Fix compositing for screen-based WebGL ShSurfs. - r=kamidphish
☠☠ backed out by ba2784ebc197 ☠ ☠
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 30 Jul 2014 10:03:07 -0700
changeset 196831 aef0101ff775f84afd261825a6c6b7b92055e858
parent 196830 834a458dae0b5c87511a730d2ece4f80b6c610ae
child 196832 917b5e49c7f4c9bef65214ff140dedf0db7381a5
push id46978
push userjgilbert@mozilla.com
push dateWed, 30 Jul 2014 17:03:16 +0000
treeherdermozilla-inbound@aef0101ff775 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskamidphish
bugs1045955
milestone34.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 1045955 - Fix compositing for screen-based WebGL ShSurfs. - r=kamidphish
dom/canvas/WebGLContext.cpp
gfx/gl/GLBlitHelper.cpp
gfx/gl/GLBlitHelper.h
gfx/gl/SharedSurface.cpp
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -1472,19 +1472,23 @@ void
 WebGLContext::MakeContextCurrent() const { gl->MakeCurrent(); }
 
 mozilla::TemporaryRef<mozilla::gfx::SourceSurface>
 WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
 {
     if (!gl)
         return nullptr;
 
-    RefPtr<DataSourceSurface> surf = Factory::CreateDataSourceSurfaceWithStride(IntSize(mWidth, mHeight),
-                                                                                SurfaceFormat::B8G8R8A8,
-                                                                                mWidth * 4);
+    bool hasAlpha = mOptions.alpha;
+    SurfaceFormat surfFormat = hasAlpha ? SurfaceFormat::B8G8R8A8
+                                        : SurfaceFormat::B8G8R8X8;
+    RefPtr<DataSourceSurface> surf;
+    surf = Factory::CreateDataSourceSurfaceWithStride(IntSize(mWidth, mHeight),
+                                                      surfFormat,
+                                                      mWidth * 4);
     if (!surf) {
         return nullptr;
     }
 
     gl->MakeCurrent();
     {
         ScopedBindFramebuffer autoFB(gl, 0);
         ClearBackbufferIfNeeded();
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -541,55 +541,63 @@ GLBlitHelper::DeleteTexBlitProgram()
         mGL->fDeleteProgram(mTexYUVPlanarBlit_Program);
         mTexYUVPlanarBlit_Program = 0;
     }
 }
 
 void
 GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
                                            const gfx::IntSize& srcSize,
-                                           const gfx::IntSize& destSize)
+                                           const gfx::IntSize& destSize,
+                                           bool internalFBs)
 {
     MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
     MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
 
     MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
 
     ScopedBindFramebuffer boundFB(mGL);
     ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
 
-    mGL->BindReadFB(srcFB);
-    mGL->BindDrawFB(destFB);
+    if (internalFBs) {
+        mGL->Screen()->BindReadFB_Internal(srcFB);
+        mGL->Screen()->BindDrawFB_Internal(destFB);
+    } else {
+        mGL->BindReadFB(srcFB);
+        mGL->BindDrawFB(destFB);
+    }
 
     mGL->fBlitFramebuffer(0, 0,  srcSize.width,  srcSize.height,
                           0, 0, destSize.width, destSize.height,
                           LOCAL_GL_COLOR_BUFFER_BIT,
                           LOCAL_GL_NEAREST);
 }
 
 void
 GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
                                            const gfx::IntSize& srcSize,
                                            const gfx::IntSize& destSize,
-                                           const GLFormats& srcFormats)
+                                           const GLFormats& srcFormats,
+                                           bool internalFBs)
 {
     MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
     MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
 
     if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
         BlitFramebufferToFramebuffer(srcFB, destFB,
-                                     srcSize, destSize);
+                                     srcSize, destSize,
+                                     internalFBs);
         return;
     }
 
     GLuint tex = CreateTextureForOffscreen(mGL, srcFormats, srcSize);
     MOZ_ASSERT(tex);
 
-    BlitFramebufferToTexture(srcFB, tex, srcSize, srcSize);
-    BlitTextureToFramebuffer(tex, destFB, srcSize, destSize);
+    BlitFramebufferToTexture(srcFB, tex, srcSize, srcSize, internalFBs);
+    BlitTextureToFramebuffer(tex, destFB, srcSize, destSize, internalFBs);
 
     mGL->fDeleteTextures(1, &tex);
 }
 
 void
 GLBlitHelper::BindAndUploadYUVTexture(Channel which,
                                       uint32_t width,
                                       uint32_t height,
@@ -777,27 +785,29 @@ GLBlitHelper::BlitImageToTexture(layers:
 
     return false;
 }
 
 void
 GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
                                        const gfx::IntSize& srcSize,
                                        const gfx::IntSize& destSize,
-                                       GLenum srcTarget)
+                                       GLenum srcTarget,
+                                       bool internalFBs)
 {
     MOZ_ASSERT(mGL->fIsTexture(srcTex));
     MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
 
     if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
         ScopedFramebufferForTexture srcWrapper(mGL, srcTex, srcTarget);
         MOZ_ASSERT(srcWrapper.IsComplete());
 
         BlitFramebufferToFramebuffer(srcWrapper.FB(), destFB,
-                                     srcSize, destSize);
+                                     srcSize, destSize,
+                                     internalFBs);
         return;
     }
 
     BlitType type;
     switch (srcTarget)
     {
     case LOCAL_GL_TEXTURE_2D:
         type = BlitTex2D;
@@ -808,48 +818,61 @@ GLBlitHelper::BlitTextureToFramebuffer(G
     default:
         printf_stderr("Fatal Error: Failed to prepare to blit texture->framebuffer.\n");
         MOZ_CRASH();
         break;
     }
 
     ScopedGLDrawState autoStates(mGL);
 
+    if (internalFBs) {
+        mGL->Screen()->BindDrawFB_Internal(destFB);
+    } else {
+        mGL->BindDrawFB(destFB);
+    }
+
     // Does destructive things to (only!) what we just saved above.
     bool good = UseTexQuadProgram(type, srcSize);
     if (!good) {
         // We're up against the wall, so bail.
         // This should really be MOZ_CRASH(why) or MOZ_RUNTIME_ASSERT(good).
         printf_stderr("[%s:%d] Fatal Error: Failed to prepare to blit texture->framebuffer.\n");
         MOZ_CRASH();
     }
     mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
 }
 
 void
 GLBlitHelper::BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
                                        const gfx::IntSize& srcSize,
                                        const gfx::IntSize& destSize,
-                                       GLenum destTarget)
+                                       GLenum destTarget,
+                                       bool internalFBs)
 {
     MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
     MOZ_ASSERT(mGL->fIsTexture(destTex));
 
     if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
         ScopedFramebufferForTexture destWrapper(mGL, destTex, destTarget);
 
         BlitFramebufferToFramebuffer(srcFB, destWrapper.FB(),
-                                     srcSize, destSize);
+                                     srcSize, destSize, internalFBs);
         return;
     }
 
     ScopedBindTexture autoTex(mGL, destTex, destTarget);
-    ScopedBindFramebuffer boundFB(mGL, srcFB);
+    ScopedBindFramebuffer boundFB(mGL);
     ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
 
+    if (internalFBs) {
+        mGL->Screen()->BindReadFB_Internal(srcFB);
+    } else {
+        mGL->BindReadFB(srcFB);
+    }
+
     mGL->fCopyTexSubImage2D(destTarget, 0,
                        0, 0,
                        0, 0,
                        srcSize.width, srcSize.height);
 }
 
 void
 GLBlitHelper::BlitTextureToTexture(GLuint srcTex, GLuint destTex,
--- a/gfx/gl/GLBlitHelper.h
+++ b/gfx/gl/GLBlitHelper.h
@@ -148,35 +148,42 @@ public:
     GLBlitHelper(GLContext* gl);
     ~GLBlitHelper();
 
     // If you don't have |srcFormats| for the 2nd definition,
     // then you'll need the framebuffer_blit extensions to use
     // the first BlitFramebufferToFramebuffer.
     void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
                                       const gfx::IntSize& srcSize,
-                                      const gfx::IntSize& destSize);
+                                      const gfx::IntSize& destSize,
+                                      bool internalFBs = false);
     void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
                                       const gfx::IntSize& srcSize,
                                       const gfx::IntSize& destSize,
-                                      const GLFormats& srcFormats);
+                                      const GLFormats& srcFormats,
+                                      bool internalFBs = false);
     void BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
                                   const gfx::IntSize& srcSize,
                                   const gfx::IntSize& destSize,
-                                  GLenum srcTarget = LOCAL_GL_TEXTURE_2D);
+                                  GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
+                                  bool internalFBs = false);
     void BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
                                   const gfx::IntSize& srcSize,
                                   const gfx::IntSize& destSize,
-                                  GLenum destTarget = LOCAL_GL_TEXTURE_2D);
+                                  GLenum destTarget = LOCAL_GL_TEXTURE_2D,
+                                  bool internalFBs = false);
     void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
                               const gfx::IntSize& srcSize,
                               const gfx::IntSize& destSize,
                               GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
                               GLenum destTarget = LOCAL_GL_TEXTURE_2D);
-    bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize,
-                            GLuint destTex, GLenum destTarget, bool yFlip = false, GLuint xoffset = 0,
-                            GLuint yoffset = 0, GLuint width = 0, GLuint height = 0);
+    bool BlitImageToTexture(layers::Image* srcImage,
+                            const gfx::IntSize& destSize,
+                            GLuint destTex, GLenum destTarget,
+                            bool yFlip = false,
+                            GLuint xoffset = 0, GLuint yoffset = 0,
+                            GLuint width = 0, GLuint height = 0);
 };
 
 }
 }
 
 #endif // GLBLITHELPER_H_
--- a/gfx/gl/SharedSurface.cpp
+++ b/gfx/gl/SharedSurface.cpp
@@ -54,23 +54,26 @@ SharedSurface::ProdCopy(SharedSurface* s
             src->LockProd();
             srcNeedsUnlock = true;
         }
 
         if (dest->mAttachType == AttachmentType::GLTexture) {
             GLuint destTex = dest->ProdTexture();
             GLenum destTarget = dest->ProdTextureTarget();
 
-            gl->BlitHelper()->BlitFramebufferToTexture(0, destTex, src->mSize, dest->mSize, destTarget);
+            gl->BlitHelper()->BlitFramebufferToTexture(0, destTex,
+                                                       src->mSize, dest->mSize,
+                                                       destTarget, true);
         } else if (dest->mAttachType == AttachmentType::GLRenderbuffer) {
             GLuint destRB = dest->ProdRenderbuffer();
             ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
 
             gl->BlitHelper()->BlitFramebufferToFramebuffer(0, destWrapper.FB(),
-                                                           src->mSize, dest->mSize);
+                                                           src->mSize, dest->mSize,
+                                                           true);
         } else {
             MOZ_CRASH("Unhandled dest->mAttachType.");
         }
 
         if (srcNeedsUnlock)
             src->UnlockProd();
 
         if (origNeedsRelock)
@@ -92,23 +95,26 @@ SharedSurface::ProdCopy(SharedSurface* s
             dest->LockProd();
             destNeedsUnlock = true;
         }
 
         if (src->mAttachType == AttachmentType::GLTexture) {
             GLuint srcTex = src->ProdTexture();
             GLenum srcTarget = src->ProdTextureTarget();
 
-            gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, 0, src->mSize, dest->mSize, srcTarget);
+            gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, 0,
+                                                       src->mSize, dest->mSize,
+                                                       srcTarget, true);
         } else if (src->mAttachType == AttachmentType::GLRenderbuffer) {
             GLuint srcRB = src->ProdRenderbuffer();
             ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB);
 
             gl->BlitHelper()->BlitFramebufferToFramebuffer(srcWrapper.FB(), 0,
-                                                           src->mSize, dest->mSize);
+                                                           src->mSize, dest->mSize,
+                                                           true);
         } else {
             MOZ_CRASH("Unhandled src->mAttachType.");
         }
 
         if (destNeedsUnlock)
             dest->UnlockProd();
 
         if (origNeedsRelock)