Bug 1444432 - Create Compositor::BlitRenderTarget and implement it for CompositorOGL. r?jrmuizel
MozReview-Commit-ID: Jz3bawvz1pv
--- 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,