Add support for framebuffer blit extension

Resolving of blit function and method in GLRenderTarget to blit
from the framebuffer to the RenderTarget.

REVIEW: 102354
This commit is contained in:
Martin Gräßlin 2011-08-17 19:32:36 +02:00
parent b016b618b5
commit 225c362a04
4 changed files with 57 additions and 0 deletions

View file

@ -869,14 +869,17 @@ void ShaderManager::resetShader(ShaderType type)
/*** GLRenderTarget ***/
bool GLRenderTarget::sSupported = false;
bool GLRenderTarget::s_blitSupported = false;
QStack<GLRenderTarget*> GLRenderTarget::s_renderTargets = QStack<GLRenderTarget*>();
void GLRenderTarget::initStatic()
{
#ifdef KWIN_HAVE_OPENGLES
sSupported = true;
s_blitSupported = false;
#else
sSupported = hasGLExtension("GL_EXT_framebuffer_object") && glFramebufferTexture2D;
s_blitSupported = hasGLExtension("GL_EXT_framebuffer_blit");
#endif
}
@ -885,6 +888,11 @@ bool GLRenderTarget::isRenderTargetBound()
return !s_renderTargets.isEmpty();
}
bool GLRenderTarget::blitSupported()
{
return s_blitSupported;
}
void GLRenderTarget::pushRenderTarget(GLRenderTarget* target)
{
target->enable();
@ -1037,6 +1045,25 @@ void GLRenderTarget::initFBO()
mValid = true;
}
void GLRenderTarget::blitFromFramebuffer(const QRect &source, const QRect &destination, GLenum filter)
{
if (!GLRenderTarget::blitSupported()) {
return;
}
#ifndef KWIN_HAVE_OPENGLES
GLRenderTarget::pushRenderTarget(this);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
const QRect s = source.isNull() ? QRect(0, 0, displayWidth(), displayHeight()) : source;
const QRect d = destination.isNull() ? QRect(0, 0, mTexture->width(), mTexture->height()) : destination;
glBlitFramebuffer(s.x(), displayHeight() - s.y() - s.height(), s.x() + s.width(), displayHeight() - s.y(),
d.x(), mTexture->height() - d.y() - d.height(), d.x() + d.width(), mTexture->height() - d.y(),
GL_COLOR_BUFFER_BIT, filter);
GLRenderTarget::popRenderTarget();
#endif
}
//*********************************
// GLVertexBufferPrivate

View file

@ -412,6 +412,27 @@ public:
static void pushRenderTarget(GLRenderTarget *target);
static GLRenderTarget *popRenderTarget();
static bool isRenderTargetBound();
/**
* Whether the GL_EXT_framebuffer_blit extension is supported.
* This functionality is not available in OpenGL ES 2.0.
*
* @returns whether framebuffer blitting is supported.
* @since 4.8
**/
static bool blitSupported();
/**
* Blits the content of the current draw framebuffer into the texture attached to this FBO.
*
* Be aware that framebuffer blitting may not be supported on all hardware. Use @link blitSupported to check whether
* it is supported.
* @param source Geometry in screen coordinates which should be blitted, if not specified complete framebuffer is used
* @param destination Geometry in attached texture, if not specified complete texture is used as destination
* @param filter The filter to use if blitted content needs to be scaled.
* @see blitSupported
* @since 4.8
**/
void blitFromFramebuffer(const QRect &source = QRect(), const QRect &destination = QRect(), GLenum filter = GL_LINEAR);
protected:
@ -420,6 +441,7 @@ protected:
private:
static bool sSupported;
static bool s_blitSupported;
static QStack<GLRenderTarget*> s_renderTargets;
GLTexture* mTexture;

View file

@ -79,6 +79,7 @@ glFramebufferTexture3D_func glFramebufferTexture3D;
glFramebufferRenderbuffer_func glFramebufferRenderbuffer;
glGetFramebufferAttachmentParameteriv_func glGetFramebufferAttachmentParameteriv;
glGenerateMipmap_func glGenerateMipmap;
glBlitFramebuffer_func glBlitFramebuffer;
// Shader functions
glCreateShader_func glCreateShader;
glShaderSource_func glShaderSource;
@ -225,6 +226,11 @@ void glResolveFunctions()
glGetFramebufferAttachmentParameteriv = NULL;
glGenerateMipmap = NULL;
}
if (hasGLExtension("GL_EXT_framebuffer_blit")) {
glBlitFramebuffer = (glBlitFramebuffer_func) getProcAddress("glBlitFramebufferEXT");
} else {
glBlitFramebuffer = NULL;
}
if (hasGLExtension("GL_ARB_shading_language_100") && hasGLExtension("GL_ARB_fragment_shader")) {
GL_RESOLVE_WITH_EXT(glCreateShader, glCreateShaderObjectARB);
GL_RESOLVE_WITH_EXT(glShaderSource, glShaderSourceARB);

View file

@ -232,6 +232,7 @@ typedef void (*glFramebufferTexture3D_func)(GLenum target, GLenum attachment, GL
typedef void (*glFramebufferRenderbuffer_func)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
typedef void (*glGetFramebufferAttachmentParameteriv_func)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
typedef void (*glGenerateMipmap_func)(GLenum target);
typedef void (*glBlitFramebuffer_func)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
extern KWIN_EXPORT glIsRenderbuffer_func glIsRenderbuffer;
extern KWIN_EXPORT glBindRenderbuffer_func glBindRenderbuffer;
extern KWIN_EXPORT glDeleteRenderbuffers_func glDeleteRenderbuffers;
@ -249,6 +250,7 @@ extern KWIN_EXPORT glFramebufferTexture3D_func glFramebufferTexture3D;
extern KWIN_EXPORT glFramebufferRenderbuffer_func glFramebufferRenderbuffer;
extern KWIN_EXPORT glGetFramebufferAttachmentParameteriv_func glGetFramebufferAttachmentParameteriv;
extern KWIN_EXPORT glGenerateMipmap_func glGenerateMipmap;
extern KWIN_EXPORT glBlitFramebuffer_func glBlitFramebuffer;
// Shader stuff
typedef GLuint(*glCreateShader_func)(GLenum);
typedef GLvoid(*glShaderSource_func)(GLuint, GLsizei, const GLchar**, const GLint*);