summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2014-06-13 11:07:42 +0200
committerLaszlo Agocs <laszlo.agocs@digia.com>2014-06-25 16:23:52 +0200
commit79bbef7588cb0d819624034df9526b85b88a7294 (patch)
treef24d469b4b5c16297148955132ca940c693bfccf
parentee88ed8fab9ddd4d470050da7ab5583982e810f2 (diff)
Enhance msaa and blitframebuffer on ES with vendor extensions
The support already in place for ANGLE is now extended for NV. On ES 2.0 the only way to get multisampled renderbuffers and blitframebuffer is through vendor-specific extensions. QOpenGLFunctions is updated to resolve the related functions for both ANGLE and NV, in addition to EXT. Task-number: QTBUG-39187 Change-Id: I1aab805ced3d06dde3dc547221bbf833ff8e06c2 Reviewed-by: Andrew Knight <andrew.knight@digia.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp21
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp24
2 files changed, 32 insertions, 13 deletions
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 75f5a9fbfb..2651c23665 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -427,18 +427,21 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Framebuffers))
return;
-
// Fall back to using a normal non-msaa FBO if we don't have support for MSAA
if (!funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)
|| !funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit)) {
samples = 0;
}
-#ifndef QT_OPENGL_ES_2
- GLint maxSamples;
- funcs.glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
- samples = qBound(0, int(samples), int(maxSamples));
-#endif
+ // On GLES 2.0 multisampled framebuffers are available through vendor-specific extensions
+ const bool msaaES2 = ctx->isOpenGLES() && (ctx->hasExtension("GL_ANGLE_framebuffer_multisample")
+ || ctx->hasExtension("GL_NV_framebuffer_multisample"));
+
+ if (!ctx->isOpenGLES() || msaaES2) {
+ GLint maxSamples;
+ funcs.glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
+ samples = qBound(0, int(samples), int(maxSamples));
+ }
size = sz;
target = texture_target;
@@ -459,11 +462,9 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
} else {
GLenum storageFormat = internal_format;
#ifdef GL_RGBA8_OES
- // Correct the internal format used by the render buffer when using ANGLE
- if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && internal_format == GL_RGBA
- && strstr((const char *)funcs.glGetString(GL_RENDERER), "ANGLE") != 0) {
+ // Correct the internal format used by the render buffer when using ES with extensions
+ if (msaaES2 && internal_format == GL_RGBA)
storageFormat = GL_RGBA8_OES;
- }
#endif
mipmap = false;
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index a616ae7a5e..e38aec846e 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -391,6 +391,10 @@ static int qt_gl_resolve_extensions()
extensions |= QOpenGLExtensions::FramebufferBlit;
if (extensionMatcher.match("GL_ANGLE_framebuffer_multisample"))
extensions |= QOpenGLExtensions::FramebufferMultisample;
+ if (extensionMatcher.match("GL_NV_framebuffer_blit"))
+ extensions |= QOpenGLExtensions::FramebufferBlit;
+ if (extensionMatcher.match("GL_NV_framebuffer_multisample"))
+ extensions |= QOpenGLExtensions::FramebufferMultisample;
} else {
extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
@@ -2031,7 +2035,9 @@ namespace {
enum ResolvePolicy
{
ResolveOES = 0x1,
- ResolveEXT = 0x2
+ ResolveEXT = 0x2,
+ ResolveANGLE = 0x4,
+ ResolveNV = 0x8
};
template <typename Base, typename FuncType, int Policy, typename ReturnType>
@@ -2153,6 +2159,12 @@ private:
if ((Policy & ResolveEXT) && !(funcs->*funcPointerName)) \
funcs->*funcPointerName = (FuncType)context->getProcAddress(funcName + "EXT"); \
\
+ if ((Policy & ResolveANGLE) && !(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(funcName + "ANGLE"); \
+ \
+ if ((Policy & ResolveNV) && !(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(funcName + "NV"); \
+ \
if (!alternateFuncName.isEmpty() && !(funcs->*funcPointerName)) { \
funcs->*funcPointerName = (FuncType)context->getProcAddress(alternateFuncName); \
\
@@ -2164,6 +2176,12 @@ private:
\
if ((Policy & ResolveEXT) && !(funcs->*funcPointerName)) \
funcs->*funcPointerName = (FuncType)context->getProcAddress(alternateFuncName + "EXT"); \
+ \
+ if ((Policy & ResolveANGLE) && !(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(funcName + "ANGLE"); \
+ \
+ if ((Policy & ResolveNV) && !(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(funcName + "NV"); \
}
#define RESOLVER_COMMON_NON_VOID \
@@ -3160,7 +3178,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
- RESOLVE_FUNC_VOID_WITH_ALTERNATE(ResolveEXT, BlitFramebuffer, BlitFramebufferANGLE)
+ RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer)
(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
@@ -3168,7 +3186,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLen
GLenum internalFormat,
GLsizei width, GLsizei height)
{
- RESOLVE_FUNC_VOID_WITH_ALTERNATE(ResolveEXT, RenderbufferStorageMultisample, RenderbufferStorageMultisampleANGLE)
+ RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample)
(target, samples, internalFormat, width, height);
}