Bug 1444432 - Create Compositor::BlitRenderTarget and implement it for CompositorOGL. r?jrmuizel draft
authorMarkus Stange <mstange@themasta.com>
Thu, 12 Apr 2018 15:28:26 -0400
changeset 781549 744d10d9f0d774e92d7b4d994700793cb66a1f9f
parent 781548 069b79ea3abb0f897472144bc2b57a8dcfe9ce13
child 781550 4683c63356a434e5283e82a9b50d0410521ee264
push id106334
push userbmo:mstange@themasta.com
push dateFri, 13 Apr 2018 04:36:02 +0000
reviewersjrmuizel
bugs1444432
milestone61.0a1
Bug 1444432 - Create Compositor::BlitRenderTarget and implement it for CompositorOGL. r?jrmuizel MozReview-Commit-ID: Jz3bawvz1pv
gfx/gl/GLBlitHelper.cpp
gfx/gl/GLBlitHelper.h
gfx/layers/Compositor.h
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/CompositorOGL.h
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -1153,43 +1153,45 @@ GLBlitHelper::DrawBlitTextureToFramebuff
     const DrawBlitProg::BaseArgs baseArgs = { texMatrix0, yFlip, destSize, Nothing() };
     prog->Draw(baseArgs);
 }
 
 // -----------------------------------------------------------------------------
 
 void
 GLBlitHelper::BlitFramebuffer(const gfx::IntSize& srcSize,
-                              const gfx::IntSize& destSize) const
+                              const gfx::IntSize& destSize,
+                              GLuint filter) const
 {
     MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
 
     const ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
     mGL->fBlitFramebuffer(0, 0,  srcSize.width,  srcSize.height,
                           0, 0, destSize.width, destSize.height,
                           LOCAL_GL_COLOR_BUFFER_BIT,
-                          LOCAL_GL_NEAREST);
+                          filter);
 }
 
 // --
 
 void
 GLBlitHelper::BlitFramebufferToFramebuffer(const GLuint srcFB, const GLuint destFB,
                                            const gfx::IntSize& srcSize,
-                                           const gfx::IntSize& destSize) const
+                                           const gfx::IntSize& destSize,
+                                           GLuint filter) const
 {
     MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
     MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
     MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
 
     const ScopedBindFramebuffer boundFB(mGL);
     mGL->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, srcFB);
     mGL->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, destFB);
 
-    BlitFramebuffer(srcSize, destSize);
+    BlitFramebuffer(srcSize, destSize, filter);
 }
 
 void
 GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, const gfx::IntSize& srcSize,
                                        const gfx::IntSize& destSize,
                                        GLenum srcTarget) const
 {
     MOZ_ASSERT(mGL->fIsTexture(srcTex));
--- a/gfx/gl/GLBlitHelper.h
+++ b/gfx/gl/GLBlitHelper.h
@@ -158,20 +158,22 @@ public:
                    OriginPos destOrigin) const;
 #endif
 
     explicit GLBlitHelper(GLContext* gl);
 public:
     ~GLBlitHelper();
 
     void BlitFramebuffer(const gfx::IntSize& srcSize,
-                         const gfx::IntSize& destSize) const;
+                         const gfx::IntSize& destSize,
+                         GLuint filter = LOCAL_GL_NEAREST) const;
     void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
                                       const gfx::IntSize& srcSize,
-                                      const gfx::IntSize& destSize) const;
+                                      const gfx::IntSize& destSize,
+                                      GLuint filter = LOCAL_GL_NEAREST) const;
     void BlitFramebufferToTexture(GLuint destTex, const gfx::IntSize& srcSize,
                                   const gfx::IntSize& destSize,
                                   GLenum destTarget = LOCAL_GL_TEXTURE_2D) const;
     void BlitTextureToFramebuffer(GLuint srcTex, const gfx::IntSize& srcSize,
                                   const gfx::IntSize& destSize,
                                   GLenum srcTarget = LOCAL_GL_TEXTURE_2D) const;
     void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
                               const gfx::IntSize& srcSize,
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -276,16 +276,26 @@ public:
 
   /**
    * Create an AsyncReadbackBuffer of the specified size. Can return null.
    */
   virtual already_AddRefed<AsyncReadbackBuffer>
   CreateAsyncReadbackBuffer(const gfx::IntSize& aSize) { return nullptr; }
 
   /**
+   * Draw a part of aSource into the current render target.
+   * Scaling is done with linear filtering.
+   * Returns whether the operation was successful.
+   */
+  virtual bool
+  BlitRenderTarget(CompositingRenderTarget* aSource,
+                   const gfx::IntSize& aSourceSize,
+                   const gfx::IntSize& aDestSize) { return false; }
+
+  /**
    * Sets the given surface as the target for subsequent calls to DrawQuad.
    * Passing null as aSurface sets the screen as the target.
    */
   virtual void SetRenderTarget(CompositingRenderTarget* aSurface) = 0;
 
   /**
    * Returns the current target for rendering. Will return null if we are
    * rendering to the screen.
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -39,16 +39,17 @@
 #include "nsMathUtils.h"                // for NS_roundf
 #include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsServiceManagerUtils.h"      // for do_GetService
 #include "nsString.h"                   // for nsString, nsAutoCString, etc
 #include "ScopedGLHelpers.h"
 #include "GLReadTexImageHelper.h"
 #include "GLBlitTextureImageHelper.h"
 #include "HeapCopyOfStackArray.h"
+#include "GLBlitHelper.h"
 #include "mozilla/gfx/Swizzle.h"
 
 #if MOZ_WIDGET_ANDROID
 #include "GeneratedJNIWrappers.h"
 #endif
 
 #include "GeckoProfiler.h"
 
@@ -710,16 +711,34 @@ CompositorOGL::ReadbackRenderTarget(Comp
                           LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, 0);
 
   if (previousTarget != aSource) {
     SetRenderTarget(previousTarget);
   }
   return true;
 }
 
+bool
+CompositorOGL::BlitRenderTarget(CompositingRenderTarget* aSource,
+                                const gfx::IntSize& aSourceSize,
+                                const gfx::IntSize& aDestSize)
+{
+  if (!mGLContext->IsSupported(GLFeature::framebuffer_blit)) {
+    return false;
+  }
+  CompositingRenderTargetOGL* source =
+    static_cast<CompositingRenderTargetOGL*>(aSource);
+  GLuint srcFBO = source->GetFBO();
+  GLuint destFBO = mCurrentRenderTarget->GetFBO();
+  mGLContext->BlitHelper()->
+    BlitFramebufferToFramebuffer(srcFBO, destFBO, aSourceSize, aDestSize,
+                                 LOCAL_GL_LINEAR);
+  return true;
+}
+
 static GLenum
 GetFrameBufferInternalFormat(GLContext* gl,
                              GLuint aFrameBuffer,
                              mozilla::widget::CompositorWidget* aWidget)
 {
   if (aFrameBuffer == 0) { // default framebuffer
     return aWidget->GetGLFrameBufferFormat();
   }
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -160,16 +160,21 @@ public:
 
   virtual bool
   ReadbackRenderTarget(CompositingRenderTarget* aSource,
                        AsyncReadbackBuffer* aDest) override;
 
   virtual already_AddRefed<AsyncReadbackBuffer>
   CreateAsyncReadbackBuffer(const gfx::IntSize& aSize) override;
 
+  virtual bool
+  BlitRenderTarget(CompositingRenderTarget* aSource,
+                   const gfx::IntSize& aSourceSize,
+                   const gfx::IntSize& aDestSize) override;
+
   virtual void DrawQuad(const gfx::Rect& aRect,
                         const gfx::IntRect& aClipRect,
                         const EffectChain &aEffectChain,
                         gfx::Float aOpacity,
                         const gfx::Matrix4x4& aTransform,
                         const gfx::Rect& aVisibleRect) override;
 
   virtual void DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,