summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl/qopenglfunctions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/opengl/qopenglfunctions.cpp')
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp83
1 files changed, 80 insertions, 3 deletions
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index bc4a714c6c..43fff1c65a 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -126,6 +126,18 @@ QT_BEGIN_NAMESPACE
glFuncs.glActiveTexture(GL_TEXTURE1);
\endcode
+ An alternative approach is to query the context's associated
+ QOpenGLFunctions instance. This is somewhat faster than the previous
+ approach due to avoiding the creation of a new instance, but the difference
+ is fairly small since the internal data structures are shared, and function
+ resolving happens only once for a given context, regardless of the number of
+ QOpenGLFunctions instances initialized for it.
+
+ \code
+ QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions();
+ glFuncs->glActiveTexture(GL_TEXTURE1);
+ \endcode
+
QOpenGLFunctions provides wrappers for all OpenGL ES 2.0
functions, including the common subset of OpenGL 1.x and ES
2.0. While such functions, for example glClear() or
@@ -372,6 +384,13 @@ static int qt_gl_resolve_extensions()
if (ctx->isOpenGLES()) {
if (format.majorVersion() >= 2)
extensions |= QOpenGLExtensions::GenerateMipmap;
+
+ if (format.majorVersion() >= 3)
+ extensions |= QOpenGLExtensions::PackedDepthStencil
+ | QOpenGLExtensions::Depth24
+ | QOpenGLExtensions::ElementIndexUint
+ | QOpenGLExtensions::MapBufferRange;
+
if (extensionMatcher.match("GL_OES_mapbuffer"))
extensions |= QOpenGLExtensions::MapBuffer;
if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
@@ -387,6 +406,12 @@ 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;
+ if (format.majorVersion() >= 3)
+ extensions |= QOpenGLExtensions::FramebufferBlit | QOpenGLExtensions::FramebufferMultisample;
} else {
extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
@@ -405,6 +430,8 @@ static int qt_gl_resolve_extensions()
if (extensionMatcher.match("GL_EXT_packed_depth_stencil"))
extensions |= QOpenGLExtensions::PackedDepthStencil;
}
+ if (extensionMatcher.match("GL_ARB_map_buffer_range"))
+ extensions |= QOpenGLExtensions::MapBufferRange;
}
if (format.renderableType() == QSurfaceFormat::OpenGL && format.version() >= qMakePair(3, 2))
@@ -2027,7 +2054,9 @@ namespace {
enum ResolvePolicy
{
ResolveOES = 0x1,
- ResolveEXT = 0x2
+ ResolveEXT = 0x2,
+ ResolveANGLE = 0x4,
+ ResolveNV = 0x8
};
template <typename Base, typename FuncType, int Policy, typename ReturnType>
@@ -2149,6 +2178,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); \
\
@@ -2160,6 +2195,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 \
@@ -3144,11 +3185,36 @@ static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribPointer(GLuint indx, GL
static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum access)
{
+#ifdef QT_OPENGL_ES_3
+ // It is possible that GL_OES_map_buffer is present, but then having to
+ // differentiate between glUnmapBufferOES and glUnmapBuffer causes extra
+ // headache. QOpenGLBuffer::map() will handle this automatically, while direct
+ // calls are better off with migrating to the standard glMapBufferRange.
+ if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) {
+ qWarning("QOpenGLFunctions: glMapBuffer is not available in OpenGL ES 3.0 and up. Use glMapBufferRange instead.");
+ return 0;
+ } else
+#endif
RESOLVE_FUNC(GLvoid *, ResolveOES, MapBuffer)(target, access);
}
+static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access)
+{
+#ifdef QT_OPENGL_ES_3
+ if (QOpenGLContext::currentContext()->format().majorVersion() >= 3)
+ return ::glMapBufferRange(target, offset, length, access);
+ else
+#endif
+ RESOLVE_FUNC(GLvoid *, 0, MapBufferRange)(target, offset, length, access);
+}
+
static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target)
{
+#ifdef QT_OPENGL_ES_3
+ if (QOpenGLContext::currentContext()->format().majorVersion() >= 3)
+ return ::glUnmapBuffer(target);
+ else
+#endif
RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target);
}
@@ -3156,7 +3222,12 @@ 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)
+#ifdef QT_OPENGL_ES_3
+ if (QOpenGLContext::currentContext()->format().majorVersion() >= 3)
+ ::glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ else
+#endif
+ RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer)
(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
@@ -3164,7 +3235,12 @@ static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLen
GLenum internalFormat,
GLsizei width, GLsizei height)
{
- RESOLVE_FUNC_VOID_WITH_ALTERNATE(ResolveEXT, RenderbufferStorageMultisample, RenderbufferStorageMultisampleANGLE)
+#ifdef QT_OPENGL_ES_3
+ if (QOpenGLContext::currentContext()->format().majorVersion() >= 3)
+ ::glRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
+ else
+#endif
+ RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample)
(target, samples, internalFormat, width, height);
}
@@ -3407,6 +3483,7 @@ QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx)
: QOpenGLFunctionsPrivate(ctx)
{
MapBuffer = qopenglfResolveMapBuffer;
+ MapBufferRange = qopenglfResolveMapBufferRange;
UnmapBuffer = qopenglfResolveUnmapBuffer;
BlitFramebuffer = qopenglfResolveBlitFramebuffer;
RenderbufferStorageMultisample = qopenglfResolveRenderbufferStorageMultisample;