Dynamic GL switch on Windows

The patch introduces a new build configuration on Windows which
can be requested by passing -opengl dynamic to configure.

Platforms other than Windows (including WinRT) are not affected.
The existing Angle and desktop configurations are not affected.
These continue to function as before and Angle remains the default.

In the future, when all modules have added support for the dynamic
path, as described below, the default configuration could be changed
to be the dynamic one. This would allow providing a single set of
binaries in the official builds instead of the current two.

When requesting dynamic GL, Angle is built but QT_OPENGL_ES[_2] are
never defined. Instead, the code path that has traditionally been
desktop GL only becomes the dynamic path that has to do runtime
checks. Qt modules and applications are not linked to opengl32.dll or
libegl/glesv2.dll in this case. Instead, QtGui exports all necessary
egl/egl/gl functions which will, under the hood, forward all requests
to a dynamically loaded EGL/WGL/GL implementation.

Porting guide (better said, changes needed to prepare your code to
work with dynamic GL builds when the fallback to Angle is utilized):

1. In !QT_OPENGL_ES[_2] code branches use QOpenGLFunctions::isES() to
differentiate between desktop and ES where needed. Keep in mind that
it is the desktop GL header (plus qopenglext.h) that is included,
not the GLES one.

QtGui's proxy will handle some differences, for example calling
glClearDepth will route to glClearDepthf when needed. The built-in
eglGetProcAddress is able to retrieve pointers for standard GLES2
functions too so code resolving OpenGL 2 functions will function
in any case.

2. QT_CONFIG will contain "opengl" and "dynamicgl" in dynamic builds,
but never "angle" or "opengles2".

3. The preprocessor define QT_OPENGL_DYNAMIC is also available in
dynamic builds. The usage of this is strongly discouraged and should
not be needed anywhere except for QtGui and the platform plugin.

4. Code in need of the library handle can use
QOpenGLFunctions::platformGLHandle().

The decision on which library to load is currently based on a simple
test that creates a dummy window/context and tries to resolve an
OpenGL 2 function. If this fails, it goes for Angle. This seems to work
well on Win7 PCs for example that do not have proper graphics drivers
providing OpenGL installed but are D3D9 capable using the default drivers.

Setting QT_OPENGL to desktop or angle skips the test and forces
usage of the given GL. There are also two new application attributes
that could be used for the same purpose.

If Angle is requested but the libraries are not present, desktop is
tried. If desktop is requested, or if angle is requested but nothing
works, the EGL/WGL functions will still be callable but will return 0.
This conveniently means that eglInitialize() and such will report a failure.

Debug messages can be enabled by setting QT_OPENGLPROXY_DEBUG. This will
tell which implementation is chosen.

The textures example application is ported to OpenGL 2, the GL 1
code path is removed.

[ChangeLog][QtGui] Qt builds on Windows can now be configured for
dynamic loading of the OpenGL implementation. This can be requested
by passing -opengl dynamic to configure. In this mode no modules will
link to opengl32.dll or Angle's libegl/libglesv2. Instead, QtGui will
dynamically choose between desktop and Angle during the first GL/EGL/WGL
call. This allows deploying applications with a single set of Qt libraries
with the ability of transparently falling back to Angle in case the
opengl32.dll is not suitable, due to missing graphics drivers for example.

Task-number: QTBUG-36483
Change-Id: I716fdebbf60b355b7d9ef57d1e069eef366b4ab9
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
This commit is contained in:
Laszlo Agocs 2014-01-27 14:45:11 +01:00 committed by The Qt Project
parent f25aca5c65
commit 97c187da3c
61 changed files with 6156 additions and 1207 deletions

View File

@ -50,9 +50,7 @@ GLWidget::GLWidget(QWidget *parent, QGLWidget *shareWidget)
xRot = 0;
yRot = 0;
zRot = 0;
#ifdef QT_OPENGL_ES_2
program = 0;
#endif
}
GLWidget::~GLWidget()
@ -89,12 +87,10 @@ void GLWidget::initializeGL()
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
#ifndef QT_OPENGL_ES_2
#ifdef GL_TEXTURE_2D
glEnable(GL_TEXTURE_2D);
#endif
#ifdef QT_OPENGL_ES_2
#define PROGRAM_VERTEX_ATTRIBUTE 0
#define PROGRAM_TEXCOORD_ATTRIBUTE 1
@ -130,8 +126,6 @@ void GLWidget::initializeGL()
program->bind();
program->setUniformValue("texture", 0);
#endif
}
void GLWidget::paintGL()
@ -139,21 +133,6 @@ void GLWidget::paintGL()
qglClearColor(clearColor);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#if !defined(QT_OPENGL_ES_2)
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -10.0f);
glRotatef(xRot / 16.0f, 1.0f, 0.0f, 0.0f);
glRotatef(yRot / 16.0f, 0.0f, 1.0f, 0.0f);
glRotatef(zRot / 16.0f, 0.0f, 0.0f, 1.0f);
glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData());
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
QMatrix4x4 m;
m.ortho(-0.5f, +0.5f, +0.5f, -0.5f, 4.0f, 15.0f);
m.translate(0.0f, 0.0f, -10.0f);
@ -169,8 +148,6 @@ void GLWidget::paintGL()
program->setAttributeArray
(PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData());
#endif
for (int i = 0; i < 6; ++i) {
glBindTexture(GL_TEXTURE_2D, textures[i]);
glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
@ -181,17 +158,6 @@ void GLWidget::resizeGL(int width, int height)
{
int side = qMin(width, height);
glViewport((width - side) / 2, (height - side) / 2, side, side);
#if !defined(QT_OPENGL_ES_2)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifndef QT_OPENGL_ES
glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
#else
glOrthof(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
#endif
glMatrixMode(GL_MODELVIEW);
#endif
}
void GLWidget::mousePressEvent(QMouseEvent *event)

View File

@ -81,9 +81,7 @@ private:
GLuint textures[6];
QVector<QVector3D> vertices;
QVector<QVector2D> texCoords;
#ifdef QT_OPENGL_ES_2
QGLShaderProgram *program;
#endif
};
#endif

View File

@ -8,6 +8,7 @@
#
load(device_config)
load(qt_config)
MAKEFILE_GENERATOR = MINGW
QMAKE_PLATFORM = win32 mingw
@ -84,7 +85,7 @@ QMAKE_LIBS =
QMAKE_LIBS_CORE = -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32
QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32
QMAKE_LIBS_NETWORK = -lws2_32
QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2 = -llibEGL -llibGLESv2 -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2_DEBUG = -llibEGLd -llibGLESv2d -lgdi32 -luser32
QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
@ -110,4 +111,3 @@ QMAKE_STRIP = $${CROSS_COMPILE}strip
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
QMAKE_NM = $${CROSS_COMPILE}nm -P
load(qt_config)

View File

@ -4,6 +4,8 @@
# Written for Intel C++
#
load(qt_config)
MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32
CONFIG += incremental flat debug_and_release debug_and_release_target
@ -61,7 +63,7 @@ QMAKE_LIBS =
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib delayimp.lib
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib delayimp.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
QMAKE_LIBS_QT_ENTRY = -lqtmain
@ -72,4 +74,3 @@ QMAKE_RC = rc
include(../common/shell-win32.conf)
DSP_EXTENSION = .dsp
load(qt_config)

View File

@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2005
#
load(qt_config)
MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@ -75,7 +77,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@ -91,4 +93,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
load(qt_config)

View File

@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2008
#
load(qt_config)
MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@ -77,7 +79,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@ -93,4 +95,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
load(qt_config)

View File

@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2010
#
load(qt_config)
MAKEFILE_GENERATOR = MSBUILD
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@ -79,7 +81,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@ -95,4 +97,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcxproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
load(qt_config)

View File

@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2012
#
load(qt_config)
MAKEFILE_GENERATOR = MSBUILD
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@ -79,7 +81,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@ -95,4 +97,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcxproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
load(qt_config)

View File

@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2013
#
load(qt_config)
MAKEFILE_GENERATOR = MSBUILD
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@ -79,7 +81,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@ -95,4 +97,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcxproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
load(qt_config)

View File

@ -517,6 +517,8 @@ public:
AA_SynthesizeMouseForUnhandledTouchEvents = 12,
AA_UseHighDpiPixmaps = 13,
AA_ForceRasterWidgets = 14,
AA_UseDesktopOpenGL = 15,
AA_UseOpenGLES = 16,
// Add new attributes before this line
AA_AttributeCount

View File

@ -168,6 +168,14 @@
\value AA_ForceRasterWidgets Make top-level widgets use pure raster surfaces,
and do not support non-native GL-based child widgets.
\value AA_UseDesktopOpenGL Forces the usage of the desktop OpenGL on
platforms that use dynamic loading of the OpenGL implementation.
This value has been added in Qt 5.3.
\value AA_UseOpenGLES Forces the usage of OpenGL ES 2.0 on platforms that
use dynamic loading of the OpenGL implementation.
This value has been added in Qt 5.3.
The following values are obsolete:
\value AA_ImmediateWidgetCreation This attribute is no longer fully

View File

@ -13,11 +13,13 @@ MODULE_PLUGIN_TYPES = \
imageformats
# This is here only because the platform plugin is no module, obviously.
win32:contains(QT_CONFIG, angle) {
win32:contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
MODULE_AUX_INCLUDES = \
\$\$QT_MODULE_INCLUDE_BASE/QtANGLE
}
contains(QT_CONFIG, dynamicgl): DEFINES += QT_OPENGL_DYNAMIC_IN_GUI
load(qt_module)
# Code coverage with TestCocoon

View File

@ -337,31 +337,32 @@ int QOpenGLContextPrivate::maxTextureSize()
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
#if defined(QT_OPENGL_ES)
return max_texture_size;
#else
GLenum proxy = GL_PROXY_TEXTURE_2D;
#ifndef QT_OPENGL_ES
if (!QOpenGLFunctions::isES()) {
GLenum proxy = GL_PROXY_TEXTURE_2D;
GLint size;
GLint next = 64;
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
if (size == 0) {
return max_texture_size;
}
do {
size = next;
next = size * 2;
if (next > max_texture_size)
break;
GLint size;
GLint next = 64;
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
} while (next > size);
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
if (size == 0) {
return max_texture_size;
}
do {
size = next;
next = size * 2;
if (next > max_texture_size)
break;
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
} while (next > size);
max_texture_size = size;
}
#endif // QT_OPENGL_ES
max_texture_size = size;
return max_texture_size;
#endif
}
/*!
@ -641,6 +642,13 @@ QOpenGLFunctions *QOpenGLContext::functions() const
*/
QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionProfile &versionProfile) const
{
#ifndef QT_OPENGL_ES_2
if (QOpenGLFunctions::isES()) {
qWarning("versionFunctions: Not supported on dynamic GL ES");
return 0;
}
#endif // QT_OPENGL_ES_2
Q_D(const QOpenGLContext);
const QSurfaceFormat f = format();

View File

@ -122,4 +122,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
SOURCES += opengl/qopenglfunctions_es2.cpp
}
contains(QT_CONFIG, dynamicgl) {
win32: SOURCES += opengl/qopenglproxy_win.cpp
}
}

View File

@ -107,7 +107,17 @@ typedef GLfloat GLdouble;
# include <OpenGL/glext.h>
# else
# define GL_GLEXT_LEGACY // Prevents GL/gl.h from #including system glext.h
// In dynamic GL builds qopenglproxy will export the GL functions that are
// called also in QtGui itself. To prevent linker warnings (msvc) or errors (mingw)
// we need to make sure the prototypes do not have dllimport.
# ifdef QT_OPENGL_DYNAMIC_IN_GUI
# undef WINGDIAPI
# define WINGDIAPI
# endif // QT_OPENGL_DYNAMIC_IN_GUI
# include <GL/gl.h>
# ifdef QT_OPENGL_DYNAMIC_IN_GUI
# undef WINGDIAPI
# endif // QT_OPENGL_DYNAMIC_IN_GUI
# include <QtGui/qopenglext.h>
# endif // Q_OS_MAC
#endif

View File

@ -333,18 +333,20 @@ void QOpenGLBuffer::destroy()
bool QOpenGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
Q_D(QOpenGLBuffer);
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
return false;
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
d->funcs->glGetBufferSubData(d->type, offset, count, data);
return glGetError() == GL_NO_ERROR;
if (QOpenGLFunctions::platformGLType() != QOpenGLFunctions::GLES1) {
Q_D(QOpenGLBuffer);
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
return false;
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
d->funcs->glGetBufferSubData(d->type, offset, count, data);
return glGetError() == GL_NO_ERROR;
}
#else
Q_UNUSED(offset);
Q_UNUSED(data);
Q_UNUSED(count);
return false;
#endif
return false;
}
/*!

View File

@ -164,7 +164,10 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[NonPremultipliedImageSrcFragmentShader] = qopenglslNonPremultipliedImageSrcFragmentShader;
code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader; // Calls "customShader", which must be appended
code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader;
code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader;
if (QOpenGLFunctions::isES())
code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_ES;
else
code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_desktop;
code[TextureBrushSrcWithPatternFragmentShader] = qopenglslTextureBrushSrcWithPatternFragmentShader;
code[PatternBrushSrcFragmentShader] = qopenglslPatternBrushSrcFragmentShader;
code[LinearGradientBrushSrcFragmentShader] = qopenglslLinearGradientBrushSrcFragmentShader;

View File

@ -305,25 +305,23 @@ static const char* const qopenglslPositionWithTextureBrushVertexShader = "\n\
static const char* const qopenglslAffinePositionWithTextureBrushVertexShader
= qopenglslPositionWithTextureBrushVertexShader;
#if defined(QT_OPENGL_ES_2)
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
// TODO: Special case POT textures which don't need this emulation
static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
static const char* const qopenglslTextureBrushSrcFragmentShader_ES = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() { \n\
return texture2D(brushTexture, fract(brushTextureCoords)); \n\
}\n";
#else
static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
static const char* const qopenglslTextureBrushSrcFragmentShader_desktop = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
{ \n\
return texture2D(brushTexture, brushTextureCoords); \n\
}\n";
#endif
static const char* const qopenglslTextureBrushSrcWithPatternFragmentShader = "\n\
varying highp vec2 brushTextureCoords; \n\

View File

@ -72,8 +72,6 @@ QT_BEGIN_NAMESPACE
#define QT_CHECK_GLERROR() {}
#endif
// ####TODO Properly #ifdef this class to use #define symbols actually defined
// by OpenGL/ES includes
#ifndef GL_MAX_SAMPLES
#define GL_MAX_SAMPLES 0x8D57
#endif
@ -592,30 +590,29 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
#ifdef QT_OPENGL_ES
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT24, size.width(), size.height());
if (QOpenGLFunctions::isES()) {
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24))
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT24, size.width(), size.height());
else
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT16, size.width(), size.height());
} else {
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT16, size.width(), size.height());
GL_DEPTH_COMPONENT, size.width(), size.height());
}
#else
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
} else {
#ifdef QT_OPENGL_ES
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
size.width(), size.height());
if (QOpenGLFunctions::isES()) {
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
size.width(), size.height());
} else {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
size.width(), size.height());
}
} else {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
size.width(), size.height());
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
}
#else
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
#endif
}
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_buffer);
@ -630,23 +627,18 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
funcs.glGenRenderbuffers(1, &stencil_buffer);
funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
#ifdef QT_OPENGL_ES
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_STENCIL_INDEX8, size.width(), size.height());
GLenum storage = GL_STENCIL_INDEX8;
#else
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_STENCIL_INDEX, size.width(), size.height());
GLenum storage = QOpenGLFunctions::isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
#endif
} else {
#ifdef QT_OPENGL_ES
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
size.width(), size.height());
#else
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
size.width(), size.height());
#endif
}
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height());
else
funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height());
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_buffer);
valid = checkFramebufferStatus(ctx);
@ -779,7 +771,13 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum tar
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
d->init(this, size, NoAttachment, target,
#ifndef QT_OPENGL_ES_2
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
#else
GL_RGBA
#endif
);
}
/*! \overload
@ -793,7 +791,13 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
d->init(this, QSize(width, height), NoAttachment, target,
#ifndef QT_OPENGL_ES_2
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
#else
GL_RGBA
#endif
);
}
/*! \overload
@ -842,6 +846,12 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
if (!internal_format)
#ifdef QT_OPENGL_ES_2
internal_format = GL_RGBA;
#else
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
#endif
d->init(this, QSize(width, height), attachment, target, internal_format);
}
@ -863,6 +873,12 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
if (!internal_format)
#ifdef QT_OPENGL_ES_2
internal_format = GL_RGBA;
#else
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
#endif
d->init(this, size, attachment, target, internal_format);
}

View File

@ -69,17 +69,11 @@ public:
explicit QOpenGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D);
QOpenGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D);
#if !defined(QT_OPENGL_ES) || defined(Q_QDOC)
QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QOpenGLFramebufferObject(int width, int height, Attachment attachment,
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
#else
QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
QOpenGLFramebufferObject(int width, int height, Attachment attachment,
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
#endif
GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format);
QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format);

View File

@ -59,12 +59,6 @@
QT_BEGIN_NAMESPACE
#ifndef QT_OPENGL_ES
#define DEFAULT_FORMAT GL_RGBA8
#else
#define DEFAULT_FORMAT GL_RGBA
#endif
class QOpenGLFramebufferObjectFormatPrivate
{
public:
@ -73,9 +67,13 @@ public:
samples(0),
attachment(QOpenGLFramebufferObject::NoAttachment),
target(GL_TEXTURE_2D),
internal_format(DEFAULT_FORMAT),
mipmap(false)
{
#ifndef QT_OPENGL_ES_2
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
#else
internal_format = GL_RGBA;
#endif
}
QOpenGLFramebufferObjectFormatPrivate
(const QOpenGLFramebufferObjectFormatPrivate *other)

View File

@ -249,98 +249,98 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context)
static int qt_gl_resolve_features()
{
#if defined(QT_OPENGL_ES_2)
int features = QOpenGLFunctions::Multitexture |
QOpenGLFunctions::Shaders |
QOpenGLFunctions::Buffers |
QOpenGLFunctions::Framebuffers |
QOpenGLFunctions::BlendColor |
QOpenGLFunctions::BlendEquation |
QOpenGLFunctions::BlendEquationSeparate |
QOpenGLFunctions::BlendFuncSeparate |
QOpenGLFunctions::BlendSubtract |
QOpenGLFunctions::CompressedTextures |
QOpenGLFunctions::Multisample |
QOpenGLFunctions::StencilSeparate;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_IMG_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures;
if (extensions.match("GL_OES_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures |
QOpenGLFunctions::NPOTTextureRepeat;
return features;
#elif defined(QT_OPENGL_ES)
int features = QOpenGLFunctions::Multitexture |
QOpenGLFunctions::Buffers |
QOpenGLFunctions::CompressedTextures |
QOpenGLFunctions::Multisample;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_OES_framebuffer_object"))
features |= QOpenGLFunctions::Framebuffers;
if (extensions.match("GL_OES_blend_equation_separate"))
features |= QOpenGLFunctions::BlendEquationSeparate;
if (extensions.match("GL_OES_blend_func_separate"))
features |= QOpenGLFunctions::BlendFuncSeparate;
if (extensions.match("GL_OES_blend_subtract"))
features |= QOpenGLFunctions::BlendSubtract;
if (extensions.match("GL_OES_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures;
if (extensions.match("GL_IMG_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures;
return features;
#else
int features = 0;
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
QOpenGLExtensionMatcher extensions;
if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES2) {
int features = QOpenGLFunctions::Multitexture |
QOpenGLFunctions::Shaders |
QOpenGLFunctions::Buffers |
QOpenGLFunctions::Framebuffers |
QOpenGLFunctions::BlendColor |
QOpenGLFunctions::BlendEquation |
QOpenGLFunctions::BlendEquationSeparate |
QOpenGLFunctions::BlendFuncSeparate |
QOpenGLFunctions::BlendSubtract |
QOpenGLFunctions::CompressedTextures |
QOpenGLFunctions::Multisample |
QOpenGLFunctions::StencilSeparate;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_IMG_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures;
if (extensions.match("GL_OES_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures |
QOpenGLFunctions::NPOTTextureRepeat;
return features;
} else if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES1) {
int features = QOpenGLFunctions::Multitexture |
QOpenGLFunctions::Buffers |
QOpenGLFunctions::CompressedTextures |
QOpenGLFunctions::Multisample;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_OES_framebuffer_object"))
features |= QOpenGLFunctions::Framebuffers;
if (extensions.match("GL_OES_blend_equation_separate"))
features |= QOpenGLFunctions::BlendEquationSeparate;
if (extensions.match("GL_OES_blend_func_separate"))
features |= QOpenGLFunctions::BlendFuncSeparate;
if (extensions.match("GL_OES_blend_subtract"))
features |= QOpenGLFunctions::BlendSubtract;
if (extensions.match("GL_OES_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures;
if (extensions.match("GL_IMG_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures;
return features;
} else {
int features = 0;
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
QOpenGLExtensionMatcher extensions;
// Recognize features by extension name.
if (extensions.match("GL_ARB_multitexture"))
features |= QOpenGLFunctions::Multitexture;
if (extensions.match("GL_ARB_shader_objects"))
features |= QOpenGLFunctions::Shaders;
if (extensions.match("GL_EXT_framebuffer_object") ||
// Recognize features by extension name.
if (extensions.match("GL_ARB_multitexture"))
features |= QOpenGLFunctions::Multitexture;
if (extensions.match("GL_ARB_shader_objects"))
features |= QOpenGLFunctions::Shaders;
if (extensions.match("GL_EXT_framebuffer_object") ||
extensions.match("GL_ARB_framebuffer_object"))
features |= QOpenGLFunctions::Framebuffers;
if (extensions.match("GL_EXT_blend_color"))
features |= QOpenGLFunctions::BlendColor;
if (extensions.match("GL_EXT_blend_equation_separate"))
features |= QOpenGLFunctions::BlendEquationSeparate;
if (extensions.match("GL_EXT_blend_func_separate"))
features |= QOpenGLFunctions::BlendFuncSeparate;
if (extensions.match("GL_EXT_blend_subtract"))
features |= QOpenGLFunctions::BlendSubtract;
if (extensions.match("GL_ARB_texture_compression"))
features |= QOpenGLFunctions::CompressedTextures;
if (extensions.match("GL_ARB_multisample"))
features |= QOpenGLFunctions::Multisample;
if (extensions.match("GL_ARB_texture_non_power_of_two"))
features |= QOpenGLFunctions::NPOTTextures;
features |= QOpenGLFunctions::Framebuffers;
if (extensions.match("GL_EXT_blend_color"))
features |= QOpenGLFunctions::BlendColor;
if (extensions.match("GL_EXT_blend_equation_separate"))
features |= QOpenGLFunctions::BlendEquationSeparate;
if (extensions.match("GL_EXT_blend_func_separate"))
features |= QOpenGLFunctions::BlendFuncSeparate;
if (extensions.match("GL_EXT_blend_subtract"))
features |= QOpenGLFunctions::BlendSubtract;
if (extensions.match("GL_ARB_texture_compression"))
features |= QOpenGLFunctions::CompressedTextures;
if (extensions.match("GL_ARB_multisample"))
features |= QOpenGLFunctions::Multisample;
if (extensions.match("GL_ARB_texture_non_power_of_two"))
features |= QOpenGLFunctions::NPOTTextures;
// assume version 2.0 or higher
features |= QOpenGLFunctions::BlendColor |
QOpenGLFunctions::BlendEquation |
QOpenGLFunctions::Multitexture |
QOpenGLFunctions::CompressedTextures |
QOpenGLFunctions::Multisample |
QOpenGLFunctions::BlendFuncSeparate |
QOpenGLFunctions::Buffers |
QOpenGLFunctions::Shaders |
QOpenGLFunctions::StencilSeparate |
QOpenGLFunctions::BlendEquationSeparate |
QOpenGLFunctions::NPOTTextures;
// assume version 2.0 or higher
features |= QOpenGLFunctions::BlendColor |
QOpenGLFunctions::BlendEquation |
QOpenGLFunctions::Multitexture |
QOpenGLFunctions::CompressedTextures |
QOpenGLFunctions::Multisample |
QOpenGLFunctions::BlendFuncSeparate |
QOpenGLFunctions::Buffers |
QOpenGLFunctions::Shaders |
QOpenGLFunctions::StencilSeparate |
QOpenGLFunctions::BlendEquationSeparate |
QOpenGLFunctions::NPOTTextures;
if (format.majorVersion() >= 3)
features |= QOpenGLFunctions::Framebuffers;
if (format.majorVersion() >= 3)
features |= QOpenGLFunctions::Framebuffers;
const QPair<int, int> version = format.version();
if (version < qMakePair(3, 0)
const QPair<int, int> version = format.version();
if (version < qMakePair(3, 0)
|| (version == qMakePair(3, 0) && format.testOption(QSurfaceFormat::DeprecatedFunctions))
|| (version == qMakePair(3, 1) && extensions.match("GL_ARB_compatibility"))
|| (version >= qMakePair(3, 2) && format.profile() == QSurfaceFormat::CompatibilityProfile)) {
features |= QOpenGLFunctions::FixedFunctionPipeline;
features |= QOpenGLFunctions::FixedFunctionPipeline;
}
return features;
}
return features;
#endif
}
static int qt_gl_resolve_extensions()
@ -350,38 +350,38 @@ static int qt_gl_resolve_extensions()
if (extensionMatcher.match("GL_EXT_bgra"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
#if defined(QT_OPENGL_ES)
if (extensionMatcher.match("GL_OES_mapbuffer"))
extensions |= QOpenGLExtensions::MapBuffer;
if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
extensions |= QOpenGLExtensions::PackedDepthStencil;
if (extensionMatcher.match("GL_OES_element_index_uint"))
extensions |= QOpenGLExtensions::ElementIndexUint;
if (extensionMatcher.match("GL_OES_depth24"))
extensions |= QOpenGLExtensions::Depth24;
// TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing.
if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
#else
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
// Recognize features by extension name.
if (format.majorVersion() >= 3
|| extensionMatcher.match("GL_ARB_framebuffer_object"))
{
extensions |= QOpenGLExtensions::FramebufferMultisample |
QOpenGLExtensions::FramebufferBlit |
QOpenGLExtensions::PackedDepthStencil;
} else {
if (extensionMatcher.match("GL_EXT_framebuffer_multisample"))
extensions |= QOpenGLExtensions::FramebufferMultisample;
if (extensionMatcher.match("GL_EXT_framebuffer_blit"))
extensions |= QOpenGLExtensions::FramebufferBlit;
if (extensionMatcher.match("GL_EXT_packed_depth_stencil"))
if (QOpenGLFunctions::isES()) {
if (extensionMatcher.match("GL_OES_mapbuffer"))
extensions |= QOpenGLExtensions::MapBuffer;
if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
extensions |= QOpenGLExtensions::PackedDepthStencil;
if (extensionMatcher.match("GL_OES_element_index_uint"))
extensions |= QOpenGLExtensions::ElementIndexUint;
if (extensionMatcher.match("GL_OES_depth24"))
extensions |= QOpenGLExtensions::Depth24;
// TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing.
if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
} else {
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
// Recognize features by extension name.
if (format.majorVersion() >= 3
|| extensionMatcher.match("GL_ARB_framebuffer_object"))
{
extensions |= QOpenGLExtensions::FramebufferMultisample |
QOpenGLExtensions::FramebufferBlit |
QOpenGLExtensions::PackedDepthStencil;
} else {
if (extensionMatcher.match("GL_EXT_framebuffer_multisample"))
extensions |= QOpenGLExtensions::FramebufferMultisample;
if (extensionMatcher.match("GL_EXT_framebuffer_blit"))
extensions |= QOpenGLExtensions::FramebufferBlit;
if (extensionMatcher.match("GL_EXT_packed_depth_stencil"))
extensions |= QOpenGLExtensions::PackedDepthStencil;
}
}
#endif
return extensions;
}
@ -2509,4 +2509,88 @@ QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx)
GetBufferSubData = qopenglfResolveGetBufferSubData;
}
#if defined(QT_OPENGL_DYNAMIC)
extern int qgl_proxyLibraryType(void);
extern HMODULE qgl_glHandle(void);
#endif
/*!
\enum QOpenGLFunctions::PlatformGLType
This enum defines the type of the underlying GL implementation.
\value DesktopGL Desktop OpenGL
\value GLES2 OpenGL ES 2.0 or higher
\value GLES1 OpenGL ES 1.x
\since 5.3
*/
/*!
\fn QOpenGLFunctions::isES()
On platforms where the OpenGL implementation is dynamically loaded
this function returns true if the underlying GL implementation is
Open GL ES.
On platforms that do not use runtime loading of the GL the return
value is based on Qt's compile-time configuration and will never
change during runtime.
\sa platformGLType()
\since 5.3
*/
/*!
Returns the underlying GL implementation type.
On platforms where the OpenGL implementation is not dynamically
loaded, the return value is determined during compile time and never
changes.
Platforms that use dynamic GL loading (e.g. Windows) cannot rely on
compile-time defines for differentiating between desktop and ES
OpenGL code. Instead, they rely on this function to query, during
runtime, the type of the loaded graphics library.
\since 5.3
*/
QOpenGLFunctions::PlatformGLType QOpenGLFunctions::platformGLType()
{
#if defined(QT_OPENGL_DYNAMIC)
return PlatformGLType(qgl_proxyLibraryType());
#elif defined(QT_OPENGL_ES_2)
return GLES2;
#elif defined(QT_OPENGL_ES)
return GLES1;
#else
return DesktopGL;
#endif
}
/*!
Returns the platform-specific handle for the OpenGL implementation that
is currently in use. (for example, a HMODULE on Windows)
On platforms that do not use dynamic GL switch the return value is null.
The library might be GL-only, meaning that windowing system interface
functions (for example EGL) may live in another, separate library.
Always use platformGLType() before resolving any functions to check if the
library implements desktop OpenGL or OpenGL ES.
\sa platformGLType()
\since 5.3
*/
void *QOpenGLFunctions::platformGLHandle()
{
#if defined(QT_OPENGL_DYNAMIC)
return qgl_glHandle();
#else
return 0;
#endif
}
QT_END_NAMESPACE

View File

@ -311,6 +311,15 @@ public:
void glVertexAttrib4fv(GLuint indx, const GLfloat* values);
void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
enum PlatformGLType {
DesktopGL = 0,
GLES2,
GLES1
};
static PlatformGLType platformGLType();
static void *platformGLHandle();
static bool isES() { return platformGLType() != DesktopGL; }
protected:
QOpenGLFunctionsPrivate *d_ptr;
static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; }
@ -322,7 +331,6 @@ struct QOpenGLFunctionsPrivate
{
QOpenGLFunctionsPrivate(QOpenGLContext *ctx);
#ifndef QT_OPENGL_ES_2
void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture);
void (QOPENGLF_APIENTRYP AttachShader)(GLuint program, GLuint shader);
void (QOPENGLF_APIENTRYP BindAttribLocation)(GLuint program, GLuint index, const char* name);
@ -418,7 +426,6 @@ struct QOpenGLFunctionsPrivate
void (QOPENGLF_APIENTRYP VertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void (QOPENGLF_APIENTRYP VertexAttrib4fv)(GLuint indx, const GLfloat* values);
void (QOPENGLF_APIENTRYP VertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
#endif
};
inline void QOpenGLFunctions::glActiveTexture(GLenum texture)

View File

@ -220,14 +220,14 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size)
currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
#if defined(QT_OPENGL_ES_2)
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
// we emulate GL_REPEAT by only taking the fractional part of the texture coords
// in the qopenglslTextureBrushSrcFragmentShader program.
GLuint wrapMode = GL_CLAMP_TO_EDGE;
#else
GLuint wrapMode = GL_REPEAT;
#endif
if (QOpenGLFunctions::isES()) {
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
// we emulate GL_REPEAT by only taking the fractional part of the texture coords
// in the qopenglslTextureBrushSrcFragmentShader program.
wrapMode = GL_CLAMP_TO_EDGE;
}
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushPixmap);
updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
@ -542,36 +542,38 @@ void QOpenGL2PaintEngineEx::beginNativePainting()
d->funcs.glDisableVertexAttribArray(i);
#ifndef QT_OPENGL_ES_2
Q_ASSERT(QOpenGLContext::currentContext());
const QOpenGLContext *ctx = d->ctx;
const QSurfaceFormat &fmt = d->device->context()->format();
if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
|| (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
|| fmt.profile() == QSurfaceFormat::CompatibilityProfile)
{
// be nice to people who mix OpenGL 1.x code with QPainter commands
// by setting modelview and projection matrices to mirror the GL 1
// paint engine
const QTransform& mtx = state()->matrix;
float mv_matrix[4][4] =
if (!QOpenGLFunctions::isES()) {
Q_ASSERT(QOpenGLContext::currentContext());
const QOpenGLContext *ctx = d->ctx;
const QSurfaceFormat &fmt = d->device->context()->format();
if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
|| (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
|| fmt.profile() == QSurfaceFormat::CompatibilityProfile)
{
{ float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
{ float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
{ 0, 0, 1, 0 },
{ float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
};
// be nice to people who mix OpenGL 1.x code with QPainter commands
// by setting modelview and projection matrices to mirror the GL 1
// paint engine
const QTransform& mtx = state()->matrix;
const QSize sz = d->device->size();
float mv_matrix[4][4] =
{
{ float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
{ float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
{ 0, 0, 1, 0 },
{ float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
};
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
const QSize sz = d->device->size();
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&mv_matrix[0][0]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&mv_matrix[0][0]);
}
}
#endif
#endif // QT_OPENGL_ES_2
d->lastTextureUsed = GLuint(-1);
d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
@ -598,11 +600,11 @@ void QOpenGL2PaintEngineExPrivate::resetGLState()
setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);
setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
#ifndef QT_OPENGL_ES_2
// gl_Color, corresponding to vertex attribute 3, may have been changed
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
funcs.glVertexAttrib4fv(3, color);
#endif
if (!QOpenGLFunctions::isES()) {
// gl_Color, corresponding to vertex attribute 3, may have been changed
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
funcs.glVertexAttrib4fv(3, color);
}
}
void QOpenGL2PaintEngineEx::endNativePainting()
@ -1332,13 +1334,15 @@ void QOpenGL2PaintEngineEx::renderHintsChanged()
{
state()->renderHintsChanged = true;
#if !defined(QT_OPENGL_ES_2)
if ((state()->renderHints & QPainter::Antialiasing)
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
glEnable(GL_MULTISAMPLE);
else
glDisable(GL_MULTISAMPLE);
#endif
#ifndef QT_OPENGL_ES_2
if (!QOpenGLFunctions::isES()) {
if ((state()->renderHints & QPainter::Antialiasing)
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
glEnable(GL_MULTISAMPLE);
else
glDisable(GL_MULTISAMPLE);
}
#endif // QT_OPENGL_ES_2
Q_D(QOpenGL2PaintEngineEx);
d->lastTextureUsed = GLuint(-1);
@ -2008,24 +2012,21 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
#if !defined(QT_OPENGL_ES_2)
glDisable(GL_MULTISAMPLE);
#endif
#ifndef QT_OPENGL_ES_2
if (!QOpenGLFunctions::isES()) {
glDisable(GL_MULTISAMPLE);
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
d->multisamplingAlwaysEnabled = false;
} else
#endif // QT_OPENGL_ES_2
{
// OpenGL ES can't switch MSAA off, so if the gl paint device is
// multisampled, it's always multisampled.
d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
}
d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
#if !defined(QT_OPENGL_ES_2)
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
#endif
#if defined(QT_OPENGL_ES_2)
// OpenGL ES can't switch MSAA off, so if the gl paint device is
// multisampled, it's always multisampled.
d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
#else
d->multisamplingAlwaysEnabled = false;
#endif
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -175,13 +175,15 @@ public:
#endif
{
#ifndef QT_OPENGL_ES_2
QSurfaceFormat f = ctx->format();
if (!QOpenGLFunctions::isES()) {
QSurfaceFormat f = ctx->format();
// Geometry shaders require OpenGL >= 3.2
if (shaderType & QOpenGLShader::Geometry)
supportsGeometryShaders = (f.version() >= qMakePair<int, int>(3, 2));
else if (shaderType & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
supportsTessellationShaders = (f.version() >= qMakePair<int, int>(4, 0));
// Geometry shaders require OpenGL >= 3.2
if (shaderType & QOpenGLShader::Geometry)
supportsGeometryShaders = (f.version() >= qMakePair<int, int>(3, 2));
else if (shaderType & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
supportsTessellationShaders = (f.version() >= qMakePair<int, int>(4, 0));
}
#endif
}
~QOpenGLShaderPrivate();
@ -441,7 +443,8 @@ bool QOpenGLShader::compileSourceCode(const char *source)
}
#ifdef QOpenGL_REDEFINE_HIGHP
if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers) {
if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers
&& QOpenGLFunctions::isES()) {
src.append(redefineHighp);
srclen.append(GLint(sizeof(redefineHighp) - 1));
}
@ -650,7 +653,8 @@ bool QOpenGLShaderProgram::init()
#ifndef QT_OPENGL_ES_2
// Resolve OpenGL 4 functions for tessellation shader support
QSurfaceFormat format = context->format();
if (format.version() >= qMakePair<int, int>(4, 0)) {
if (!QOpenGLFunctions::isES()
&& format.version() >= qMakePair<int, int>(4, 0)) {
d->tessellationFuncs = context->versionFunctions<QOpenGLFunctions_4_0_Core>();
d->tessellationFuncs->initializeOpenGLFunctions();
}
@ -3248,14 +3252,16 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
#ifndef QT_OPENGL_ES_2
// Geometry shaders require OpenGL 3.2 or newer
QSurfaceFormat format = context->format();
return (format.version() >= qMakePair<int, int>(3, 2));
return (!QOpenGLFunctions::isES())
&& (format.version() >= qMakePair<int, int>(3, 2));
#else
// No geometry shader support in OpenGL ES2
return false;
#endif
} else if (type == TessellationControl || type == TessellationEvaluation) {
#if !defined(QT_OPENGL_ES_2)
return (format.version() >= qMakePair<int, int>(4, 0));
return (!QOpenGLFunctions::isES())
&& (format.version() >= qMakePair<int, int>(4, 0));
#else
// No tessellation shader support in OpenGL ES2
return false;

View File

@ -2406,78 +2406,87 @@ bool QOpenGLTexture::hasFeature(Feature feature)
QSurfaceFormat f = ctx->format();
bool supported = false;
switch (feature) {
#if !defined(QT_OPENGL_ES_2)
case ImmutableMultisampleStorage:
case TextureBuffer:
case StencilTexturing:
supported = f.version() >= qMakePair(4, 3);
break;
if (!QOpenGLFunctions::isES()) {
switch (feature) {
case ImmutableMultisampleStorage:
case TextureBuffer:
case StencilTexturing:
supported = f.version() >= qMakePair(4, 3);
break;
case ImmutableStorage:
supported = f.version() >= qMakePair(4, 2);
break;
case ImmutableStorage:
supported = f.version() >= qMakePair(4, 2);
break;
case TextureCubeMapArrays:
supported = f.version() >= qMakePair(4, 0);
break;
case TextureCubeMapArrays:
supported = f.version() >= qMakePair(4, 0);
break;
case Swizzle:
supported = f.version() >= qMakePair(3, 3);
break;
case Swizzle:
supported = f.version() >= qMakePair(3, 3);
break;
case TextureMultisample:
supported = f.version() >= qMakePair(3, 2);
break;
case TextureMultisample:
supported = f.version() >= qMakePair(3, 2);
break;
case TextureArrays:
supported = f.version() >= qMakePair(3, 0);
break;
case TextureArrays:
supported = f.version() >= qMakePair(3, 0);
break;
case TextureRectangle:
supported = f.version() >= qMakePair(2, 1);
break;
case TextureRectangle:
supported = f.version() >= qMakePair(2, 1);
break;
case Texture3D:
supported = f.version() >= qMakePair(1, 3);
break;
case Texture3D:
supported = f.version() >= qMakePair(1, 3);
break;
case AnisotropicFiltering:
supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
break;
case AnisotropicFiltering:
supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
break;
case NPOTTextures:
case NPOTTextureRepeat:
supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
break;
case NPOTTextures:
case NPOTTextureRepeat:
supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
break;
case Texture1D:
supported = f.version() >= qMakePair(1, 1);
break;
case Texture1D:
supported = f.version() >= qMakePair(1, 1);
break;
case MaxFeatureFlag:
break;
}
case MaxFeatureFlag:
break;
#else
case Texture3D:
supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
break;
case AnisotropicFiltering:
supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
break;
case NPOTTextures:
case NPOTTextureRepeat:
supported = f.version() >= qMakePair(3,0);
if (!supported) {
supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"));
if (!supported)
supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
default:
break;
}
default:
break;
}
if (QOpenGLFunctions::isES())
#endif
{
switch (feature) {
case Texture3D:
supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
break;
case AnisotropicFiltering:
supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
break;
case NPOTTextures:
case NPOTTextureRepeat:
supported = f.version() >= qMakePair(3,0);
if (!supported) {
supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"));
if (!supported)
supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
}
default:
break;
}
}
return supported;
}
@ -2491,17 +2500,20 @@ bool QOpenGLTexture::hasFeature(Feature feature)
void QOpenGLTexture::setMipBaseLevel(int baseLevel)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->textureId);
Q_ASSERT(d->texFuncs);
Q_ASSERT(baseLevel <= d->maxLevel);
d->baseLevel = baseLevel;
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->textureId);
Q_ASSERT(d->texFuncs);
Q_ASSERT(baseLevel <= d->maxLevel);
d->baseLevel = baseLevel;
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
return;
}
#else
Q_UNUSED(baseLevel);
qWarning("QOpenGLTexture: Mipmap base level is not supported");
#endif
qWarning("QOpenGLTexture: Mipmap base level is not supported");
}
/*!
@ -2525,17 +2537,20 @@ int QOpenGLTexture::mipBaseLevel() const
void QOpenGLTexture::setMipMaxLevel(int maxLevel)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->textureId);
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->baseLevel <= maxLevel);
d->maxLevel = maxLevel;
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->textureId);
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->baseLevel <= maxLevel);
d->maxLevel = maxLevel;
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
return;
}
#else
Q_UNUSED(maxLevel);
qWarning("QOpenGLTexture: Mipmap max level is not supported");
#endif
qWarning("QOpenGLTexture: Mipmap max level is not supported");
}
/*!
@ -2559,18 +2574,21 @@ int QOpenGLTexture::mipMaxLevel() const
void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->textureId);
Q_ASSERT(d->texFuncs);
Q_ASSERT(baseLevel <= maxLevel);
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->textureId);
Q_ASSERT(d->texFuncs);
Q_ASSERT(baseLevel <= maxLevel);
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
return;
}
#else
Q_UNUSED(baseLevel);
Q_UNUSED(maxLevel);
qWarning("QOpenGLTexture: Mipmap level range is not supported");
#endif
qWarning("QOpenGLTexture: Mipmap level range is not supported");
}
/*!
@ -2666,21 +2684,24 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
void QOpenGLTexture::setSwizzleMask(SwizzleComponent component, SwizzleValue value)
{
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
if (!d->features.testFlag(Swizzle)) {
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
if (!d->features.testFlag(Swizzle)) {
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
return;
}
d->swizzleMask[component - SwizzleRed] = value;
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value);
return;
}
d->swizzleMask[component - SwizzleRed] = value;
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value);
#else
Q_UNUSED(component);
Q_UNUSED(value);
qWarning("QOpenGLTexture: Texture swizzling is not supported");
#endif
qWarning("QOpenGLTexture: Texture swizzling is not supported");
}
/*!
@ -2690,27 +2711,30 @@ void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g,
SwizzleValue b, SwizzleValue a)
{
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
if (!d->features.testFlag(Swizzle)) {
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
if (!d->features.testFlag(Swizzle)) {
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
return;
}
GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
d->swizzleMask[0] = r;
d->swizzleMask[1] = g;
d->swizzleMask[2] = b;
d->swizzleMask[3] = a;
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
return;
}
GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
d->swizzleMask[0] = r;
d->swizzleMask[1] = g;
d->swizzleMask[2] = b;
d->swizzleMask[3] = a;
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
qWarning("QOpenGLTexture: Texture swizzling is not supported");
#endif
qWarning("QOpenGLTexture: Texture swizzling is not supported");
}
/*!
@ -2736,20 +2760,23 @@ QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent compon
void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode)
{
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
if (!d->features.testFlag(StencilTexturing)) {
qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3");
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
if (!d->features.testFlag(StencilTexturing)) {
qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3");
return;
}
d->depthStencilMode = mode;
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
return;
}
d->depthStencilMode = mode;
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
#else
Q_UNUSED(mode);
qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
#endif
qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
}
/*!
@ -2923,23 +2950,26 @@ QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDire
void QOpenGLTexture::setBorderColor(QColor color)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
float values[4];
values[0] = color.redF();
values[1] = color.greenF();
values[2] = color.blueF();
values[3] = color.alphaF();
d->borderColor.clear();
for (int i = 0; i < 4; ++i)
d->borderColor.append(QVariant(values[i]));
d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
float values[4];
values[0] = color.redF();
values[1] = color.greenF();
values[2] = color.blueF();
values[3] = color.alphaF();
d->borderColor.clear();
for (int i = 0; i < 4; ++i)
d->borderColor.append(QVariant(values[i]));
d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
return;
}
#else
Q_UNUSED(color);
qWarning("QOpenGLTexture: Border color is not supported");
#endif
qWarning("QOpenGLTexture: Border color is not supported");
}
/*!
@ -2948,26 +2978,29 @@ void QOpenGLTexture::setBorderColor(QColor color)
void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
float values[4];
values[0] = r;
values[1] = g;
values[2] = b;
values[3] = a;
d->borderColor.clear();
for (int i = 0; i < 4; ++i)
d->borderColor.append(QVariant(values[i]));
d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
float values[4];
values[0] = r;
values[1] = g;
values[2] = b;
values[3] = a;
d->borderColor.clear();
for (int i = 0; i < 4; ++i)
d->borderColor.append(QVariant(values[i]));
d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
return;
}
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
qWarning("QOpenGLTexture: Border color is not supported");
#endif
qWarning("QOpenGLTexture: Border color is not supported");
}
/*!
@ -2976,26 +3009,29 @@ void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
int values[4];
values[0] = r;
values[1] = g;
values[2] = b;
values[3] = a;
d->borderColor.clear();
for (int i = 0; i < 4; ++i)
d->borderColor.append(QVariant(values[i]));
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
int values[4];
values[0] = r;
values[1] = g;
values[2] = b;
values[3] = a;
d->borderColor.clear();
for (int i = 0; i < 4; ++i)
d->borderColor.append(QVariant(values[i]));
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
return;
}
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
qWarning("QOpenGLTexture: Border color is not supported");
#endif
qWarning("QOpenGLTexture: Border color is not supported");
// TODO Handle case of using glTextureParameterIiv() based on format
}
@ -3006,26 +3042,29 @@ void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
int values[4];
values[0] = int(r);
values[1] = int(g);
values[2] = int(b);
values[3] = int(a);
d->borderColor.clear();
for (int i = 0; i < 4; ++i)
d->borderColor.append(QVariant(values[i]));
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
int values[4];
values[0] = int(r);
values[1] = int(g);
values[2] = int(b);
values[3] = int(a);
d->borderColor.clear();
for (int i = 0; i < 4; ++i)
d->borderColor.append(QVariant(values[i]));
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
return;
}
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
qWarning("QOpenGLTexture: Border color is not supported");
#endif
qWarning("QOpenGLTexture: Border color is not supported");
// TODO Handle case of using glTextureParameterIuiv() based on format
}
@ -3109,17 +3148,20 @@ void QOpenGLTexture::borderColor(unsigned int *border) const
void QOpenGLTexture::setMinimumLevelOfDetail(float value)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
Q_ASSERT(value < d->maxLevelOfDetail);
d->minLevelOfDetail = value;
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
Q_ASSERT(value < d->maxLevelOfDetail);
d->minLevelOfDetail = value;
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value);
return;
}
#else
Q_UNUSED(value);
qWarning("QOpenGLTexture: Detail level is not supported");
#endif
qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
@ -3143,17 +3185,20 @@ float QOpenGLTexture::minimumLevelOfDetail() const
void QOpenGLTexture::setMaximumLevelOfDetail(float value)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
Q_ASSERT(value > d->minLevelOfDetail);
d->maxLevelOfDetail = value;
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
Q_ASSERT(value > d->minLevelOfDetail);
d->maxLevelOfDetail = value;
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value);
return;
}
#else
Q_UNUSED(value);
qWarning("QOpenGLTexture: Detail level is not supported");
#endif
qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
@ -3176,20 +3221,23 @@ float QOpenGLTexture::maximumLevelOfDetail() const
void QOpenGLTexture::setLevelOfDetailRange(float min, float max)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
Q_ASSERT(min < max);
d->minLevelOfDetail = min;
d->maxLevelOfDetail = max;
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min);
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
Q_ASSERT(min < max);
d->minLevelOfDetail = min;
d->maxLevelOfDetail = max;
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min);
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max);
return;
}
#else
Q_UNUSED(min);
Q_UNUSED(max);
qWarning("QOpenGLTexture: Detail level is not supported");
#endif
qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
@ -3212,16 +3260,19 @@ QPair<float, float> QOpenGLTexture::levelOfDetailRange() const
void QOpenGLTexture::setLevelofDetailBias(float bias)
{
#if !defined(QT_OPENGL_ES_2)
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
d->levelOfDetailBias = bias;
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias);
if (!QOpenGLFunctions::isES()) {
Q_D(QOpenGLTexture);
d->create();
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
d->levelOfDetailBias = bias;
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias);
return;
}
#else
Q_UNUSED(bias);
qWarning("QOpenGLTexture: Detail level is not supported");
#endif
qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!

View File

@ -328,8 +328,11 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
if (mask.format() == QImage::Format_RGB32
// We need to make the alpha component equal to the average of the RGB values.
// This is needed when drawing sub-pixel antialiased text on translucent targets.
#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|| mask.format() == QImage::Format_ARGB32_Premultiplied
#else
|| (mask.format() == QImage::Format_ARGB32_Premultiplied
&& QOpenGLFunctions::isES())
#endif
) {
for (int y = 0; y < maskHeight; ++y) {
@ -345,10 +348,11 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
avg = qAlpha(src[x]);
src[x] = qRgba(r, g, b, avg);
#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
// swizzle the bits to accommodate for the GL_RGBA upload.
src[x] = ARGB2RGBA(src[x]);
#if Q_BYTE_ORDER != Q_BIG_ENDIAN
if (QOpenGLFunctions::isES())
#endif
src[x] = ARGB2RGBA(src[x]);
}
}
}
@ -356,11 +360,16 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
if (mask.depth() == 32) {
#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_RGBA, GL_UNSIGNED_BYTE, mask.bits());
#ifdef QT_OPENGL_ES_2
GLenum fmt = GL_RGBA;
#else
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
GLenum fmt = QOpenGLFunctions::isES() ? GL_RGBA : GL_BGRA;
#endif // QT_OPENGL_ES_2
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
fmt = GL_RGBA;
#endif
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, fmt, GL_UNSIGNED_BYTE, mask.bits());
} else {
// glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
// not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista

View File

@ -42,14 +42,15 @@
#include "qopengltexturehelper_p.h"
#include <QOpenGLContext>
#include <QOpenGLFunctions>
QT_BEGIN_NAMESPACE
QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
{
// Resolve EXT_direct_state_access entry points if present
#if !defined(QT_OPENGL_ES_2)
if (context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
if (!QOpenGLFunctions::isES()
&& context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
TextureParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLint )>(context->getProcAddress(QByteArrayLiteral("glTextureParameteriEXT")));
TextureParameterivEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLint *)>(context->getProcAddress(QByteArrayLiteral("glTextureParameterivEXT")));
TextureParameterfEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLfloat )>(context->getProcAddress(QByteArrayLiteral("glTextureParameterfEXT")));
@ -97,7 +98,6 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
CompressedTextureImage2D = &QOpenGLTextureHelper::dsa_CompressedTextureImage2D;
CompressedTextureImage3D = &QOpenGLTextureHelper::dsa_CompressedTextureImage3D;
} else {
#endif
// Use our own DSA emulation
TextureParameteri = &QOpenGLTextureHelper::qt_TextureParameteri;
TextureParameteriv = &QOpenGLTextureHelper::qt_TextureParameteriv;
@ -119,31 +119,28 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
CompressedTextureImage1D = &QOpenGLTextureHelper::qt_CompressedTextureImage1D;
CompressedTextureImage2D = &QOpenGLTextureHelper::qt_CompressedTextureImage2D;
CompressedTextureImage3D = &QOpenGLTextureHelper::qt_CompressedTextureImage3D;
#if !defined(QT_OPENGL_ES_2)
}
#endif
// Some DSA functions are part of NV_texture_multisample instead
#if !defined(QT_OPENGL_ES_2)
if (context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) {
if (!QOpenGLFunctions::isES()
&& context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) {
TextureImage3DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(QByteArrayLiteral("glTextureImage3DMultisampleNV")));
TextureImage2DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(QByteArrayLiteral("glTextureImage2DMultisampleNV")));
TextureImage3DMultisample = &QOpenGLTextureHelper::dsa_TextureImage3DMultisample;
TextureImage2DMultisample = &QOpenGLTextureHelper::dsa_TextureImage2DMultisample;
} else {
#endif
TextureImage3DMultisample = &QOpenGLTextureHelper::qt_TextureImage3DMultisample;
TextureImage2DMultisample = &QOpenGLTextureHelper::qt_TextureImage2DMultisample;
#if !defined(QT_OPENGL_ES_2)
}
#endif
// wglGetProcAddress should not be used to (and indeed will not) load OpenGL <= 1.1 functions.
// Hence, we resolve them "the hard way"
#if defined(Q_OS_WIN) && !defined(QT_OPENGL_ES_2)
HMODULE handle = GetModuleHandleA("opengl32.dll");
HMODULE handle = static_cast<HMODULE>(QOpenGLFunctions::platformGLHandle());
if (!handle)
handle = GetModuleHandleA("opengl32.dll");
// OpenGL 1.0
GetIntegerv = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint *)>(GetProcAddress(handle, QByteArrayLiteral("glGetIntegerv")));
@ -194,15 +191,12 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
TexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage1D")));
#endif
#if defined(QT_OPENGL_ES_2)
if (context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) {
if (QOpenGLFunctions::isES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) {
TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexImage3DOES")));
TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3DOES")));
CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES")));
CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3DOES")));
} else
#endif
{
} else {
// OpenGL 1.2
TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D")));
TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D")));
@ -239,8 +233,6 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
TextureView = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLuint , GLenum , GLuint , GLuint , GLuint , GLuint )>(context->getProcAddress(QByteArrayLiteral("glTextureView")));
}
#if !defined(QT_OPENGL_ES_2)
void QOpenGLTextureHelper::dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
{
Q_UNUSED(bindingTarget);
@ -385,8 +377,6 @@ void QOpenGLTextureHelper::dsa_CompressedTextureImage3D(GLuint texture, GLenum t
CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
}
#endif // !defined(QT_OPENGL_ES_2)
void QOpenGLTextureHelper::qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
{
GLint oldTexture;

View File

@ -256,7 +256,6 @@ public:
}
private:
#if !defined(QT_OPENGL_ES_2)
// DSA wrapper (so we can use pointer to member function as switch)
void dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
@ -332,7 +331,6 @@ private:
void dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLsizei imageSize, const GLvoid *bits);
#endif
// DSA emulation API
void qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
@ -749,7 +747,6 @@ private:
CompressedTextureImage2DMemberFunc CompressedTextureImage2D;
CompressedTextureImage3DMemberFunc CompressedTextureImage3D;
#if !defined(QT_OPENGL_ES_2)
// Raw function pointers for core and DSA functions
// EXT_direct_state_access used when DSA is available
@ -780,7 +777,6 @@ private:
// Plus some missing ones that are in the NV_texture_multisample extension instead
void (QOPENGLF_APIENTRYP TextureImage3DMultisampleNV)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
void (QOPENGLF_APIENTRYP TextureImage2DMultisampleNV)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
#endif
// OpenGL 1.0
void (QOPENGLF_APIENTRYP GetIntegerv)(GLenum pname, GLint *params);

View File

@ -44,6 +44,7 @@
#include "qopenglqueryhelper_p.h"
#include <QtCore/private/qobject_p.h>
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
QT_BEGIN_NAMESPACE
@ -123,6 +124,11 @@ public:
bool QOpenGLTimerQueryPrivate::create()
{
if (QOpenGLFunctions::isES()) {
qWarning("QOpenGLTimerQuery: Not supported on dynamic GL ES");
return false;
}
QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (timer && context == ctx)

View File

@ -43,6 +43,7 @@
#include <QtCore/private/qobject_p.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qopenglfunctions.h>
#if !defined(QT_OPENGL_ES_2)
#include <QtGui/qopenglfunctions_3_0.h>
@ -156,6 +157,13 @@ bool QOpenGLVertexArrayObjectPrivate::create()
return false;
}
#if !defined(QT_OPENGL_ES_2)
if (QOpenGLFunctions::isES()) {
qWarning("QOpenGLVertexArrayObject: Not supported on dynamic GL ES");
return false;
}
#endif
Q_Q(QOpenGLVertexArrayObject);
if (context)
QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));

View File

@ -163,7 +163,10 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader;
code[CustomImageSrcFragmentShader] = qglslCustomSrcFragmentShader; // Calls "customShader", which must be appended
code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader;
code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader;
if (!QOpenGLFunctions::isES())
code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_desktop;
else
code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_ES;
code[TextureBrushSrcWithPatternFragmentShader] = qglslTextureBrushSrcWithPatternFragmentShader;
code[PatternBrushSrcFragmentShader] = qglslPatternBrushSrcFragmentShader;
code[LinearGradientBrushSrcFragmentShader] = qglslLinearGradientBrushSrcFragmentShader;

View File

@ -305,25 +305,23 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\
static const char* const qglslAffinePositionWithTextureBrushVertexShader
= qglslPositionWithTextureBrushVertexShader;
#if defined(QT_OPENGL_ES_2)
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
// TODO: Special case POT textures which don't need this emulation
static const char* const qglslTextureBrushSrcFragmentShader = "\n\
static const char* const qglslTextureBrushSrcFragmentShader_ES = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() { \n\
return texture2D(brushTexture, fract(brushTextureCoords)); \n\
}\n";
#else
static const char* const qglslTextureBrushSrcFragmentShader = "\n\
static const char* const qglslTextureBrushSrcFragmentShader_desktop = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
{ \n\
return texture2D(brushTexture, brushTextureCoords); \n\
}\n";
#endif
static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\
varying highp vec2 brushTextureCoords; \n\

View File

@ -539,33 +539,35 @@ void QGL2PaintEngineEx::beginNativePainting()
d->funcs.glDisableVertexAttribArray(i);
#ifndef QT_OPENGL_ES_2
const QGLContext *ctx = d->ctx;
const QGLFormat &fmt = d->device->format();
if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
|| (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->contextHandle()->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
|| fmt.profile() == QGLFormat::CompatibilityProfile)
{
// be nice to people who mix OpenGL 1.x code with QPainter commands
// by setting modelview and projection matrices to mirror the GL 1
// paint engine
const QTransform& mtx = state()->matrix;
float mv_matrix[4][4] =
if (!QOpenGLFunctions::isES()) {
const QGLContext *ctx = d->ctx;
const QGLFormat &fmt = d->device->format();
if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
|| (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->contextHandle()->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
|| fmt.profile() == QGLFormat::CompatibilityProfile)
{
{ float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
{ float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
{ 0, 0, 1, 0 },
{ float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
};
// be nice to people who mix OpenGL 1.x code with QPainter commands
// by setting modelview and projection matrices to mirror the GL 1
// paint engine
const QTransform& mtx = state()->matrix;
const QSize sz = d->device->size();
float mv_matrix[4][4] =
{
{ float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
{ float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
{ 0, 0, 1, 0 },
{ float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
};
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
const QSize sz = d->device->size();
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&mv_matrix[0][0]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&mv_matrix[0][0]);
}
}
#endif
@ -595,9 +597,11 @@ void QGL2PaintEngineExPrivate::resetGLState()
ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
#ifndef QT_OPENGL_ES_2
// gl_Color, corresponding to vertex attribute 3, may have been changed
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
funcs.glVertexAttrib4fv(3, color);
if (!QOpenGLFunctions::isES()) {
// gl_Color, corresponding to vertex attribute 3, may have been changed
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
funcs.glVertexAttrib4fv(3, color);
}
#endif
}
@ -1352,11 +1356,13 @@ void QGL2PaintEngineEx::renderHintsChanged()
state()->renderHintsChanged = true;
#if !defined(QT_OPENGL_ES_2)
if ((state()->renderHints & QPainter::Antialiasing)
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
glEnable(GL_MULTISAMPLE);
else
glDisable(GL_MULTISAMPLE);
if (!QOpenGLFunctions::isES()) {
if ((state()->renderHints & QPainter::Antialiasing)
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
glEnable(GL_MULTISAMPLE);
else
glDisable(GL_MULTISAMPLE);
}
#endif
Q_D(QGL2PaintEngineEx);
@ -2027,21 +2033,23 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
glDisable(GL_SCISSOR_TEST);
#if !defined(QT_OPENGL_ES_2)
glDisable(GL_MULTISAMPLE);
if (!QOpenGLFunctions::isES())
glDisable(GL_MULTISAMPLE);
#endif
d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
#if !defined(QT_OPENGL_ES_2)
if (!QOpenGLFunctions::isES()) {
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
#endif
#if defined(QT_OPENGL_ES_2)
d->multisamplingAlwaysEnabled = false;
} else {
d->multisamplingAlwaysEnabled = d->device->format().sampleBuffers();
}
#else
// OpenGL ES can't switch MSAA off, so if the gl paint device is
// multisampled, it's always multisampled.
d->multisamplingAlwaysEnabled = d->device->format().sampleBuffers();
#else
d->multisamplingAlwaysEnabled = false;
#endif
return true;

View File

@ -319,23 +319,24 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub
uchar g = src[x] >> 8;
uchar b = src[x];
quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding.
#if defined(QT_OPENGL_ES_2)
// swizzle the bits to accommodate for the GL_RGBA upload.
src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16);
#else
src[x] = (src[x] & 0x00ffffff) | (avg << 24);
#endif
if (QOpenGLFunctions::isES()) {
// swizzle the bits to accommodate for the GL_RGBA upload.
src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16);
} else {
src[x] = (src[x] & 0x00ffffff) | (avg << 24);
}
}
}
}
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
if (mask.format() == QImage::Format_RGB32) {
#if defined(QT_OPENGL_ES_2)
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_RGBA, GL_UNSIGNED_BYTE, mask.bits());
#else
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
GLenum format = GL_RGBA;
#if !defined(QT_OPENGL_ES_2)
if (!QOpenGLFunctions::isES())
format = GL_BGRA;
#endif
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits());
} else {
// glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
// not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista

View File

@ -1699,10 +1699,12 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp
return QImage();
int w = size.width();
int h = size.height();
#if !defined(QT_OPENGL_ES_2)
//### glGetTexImage not in GL ES 2.0, need to do something else here!
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
#endif
#ifndef QT_OPENGL_ES
if (!QOpenGLFunctions::isES()) {
//### glGetTexImage not in GL ES 2.0, need to do something else here!
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
}
#endif // QT_OPENGL_ES
convertFromGLImage(img, w, h, alpha_format, include_alpha);
return img;
}
@ -2282,17 +2284,20 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
glBindTexture(target, tx_id);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering);
#if defined(QT_OPENGL_ES_2)
bool genMipmap = false;
#endif
bool genMipmap = !QOpenGLFunctions::isES();
if (glFormat.directRendering()
&& (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::GenerateMipmap))
&& target == GL_TEXTURE_2D
&& (options & QGLContext::MipmapBindOption))
{
#if !defined(QT_OPENGL_ES_2)
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
if (genMipmap) {
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
} else {
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
genMipmap = true;
}
#else
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
genMipmap = true;
@ -2421,11 +2426,11 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
printf(" - did byte swapping (%d ms)\n", time.elapsed());
#endif
}
#ifdef QT_OPENGL_ES
// OpenGL/ES requires that the internal and external formats be
// identical.
internalFormat = externalFormat;
#endif
if (QOpenGLFunctions::isES()) {
// OpenGL/ES requires that the internal and external formats be
// identical.
internalFormat = externalFormat;
}
#ifdef QGL_BIND_TEXTURE_DEBUG
printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
img.format(), externalFormat, internalFormat, pixel_type);
@ -2434,10 +2439,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
const QImage &constRef = img; // to avoid detach in bits()...
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
pixel_type, constRef.bits());
#if defined(QT_OPENGL_ES_2)
if (genMipmap)
glGenerateMipmap(target);
#endif
if (genMipmap && QOpenGLFunctions::isES())
functions->glGenerateMipmap(target);
#ifndef QT_NO_DEBUG
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
@ -2518,31 +2521,32 @@ int QGLContextPrivate::maxTextureSize()
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
#if defined(QT_OPENGL_ES)
return max_texture_size;
#else
GLenum proxy = GL_PROXY_TEXTURE_2D;
#ifndef QT_OPENGL_ES
if (!QOpenGLFunctions::isES()) {
GLenum proxy = GL_PROXY_TEXTURE_2D;
GLint size;
GLint next = 64;
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
if (size == 0) {
return max_texture_size;
}
do {
size = next;
next = size * 2;
if (next > max_texture_size)
break;
GLint size;
GLint next = 64;
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
} while (next > size);
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
if (size == 0) {
return max_texture_size;
}
do {
size = next;
next = size * 2;
max_texture_size = size;
return max_texture_size;
if (next > max_texture_size)
break;
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
} while (next > size);
max_texture_size = size;
}
#endif
return max_texture_size;
}
/*!
@ -2696,7 +2700,7 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
Q_UNUSED(textureHeight);
Q_UNUSED(textureTarget);
#else
if (textureTarget != GL_TEXTURE_2D) {
if (textureTarget != GL_TEXTURE_2D && !QOpenGLFunctions::isES()) {
if (textureWidth == -1 || textureHeight == -1) {
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
@ -2763,35 +2767,38 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
#endif
#ifndef QT_OPENGL_ES_2
if (!QOpenGLFunctions::isES()) {
#ifdef QT_OPENGL_ES
if (textureTarget != GL_TEXTURE_2D) {
qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
if (textureTarget != GL_TEXTURE_2D) {
qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
return;
}
#else
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
GLint oldTexture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
#endif
glEnable(textureTarget);
glBindTexture(textureTarget, textureId);
qDrawTextureRect(target, -1, -1, textureTarget);
#ifdef QT_OPENGL_ES
glDisable(textureTarget);
#else
if (!wasEnabled)
glDisable(textureTarget);
glBindTexture(textureTarget, oldTexture);
#endif
return;
}
#else
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
GLint oldTexture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
#endif
glEnable(textureTarget);
glBindTexture(textureTarget, textureId);
qDrawTextureRect(target, -1, -1, textureTarget);
#ifdef QT_OPENGL_ES
glDisable(textureTarget);
#else
if (!wasEnabled)
glDisable(textureTarget);
glBindTexture(textureTarget, oldTexture);
#endif
#else
Q_UNUSED(target);
Q_UNUSED(textureId);
Q_UNUSED(textureTarget);
qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine");
#endif
qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine");
}
/*!
@ -2821,40 +2828,42 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
Q_UNUSED(point);
Q_UNUSED(textureId);
Q_UNUSED(textureTarget);
qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead");
#else
if (!QOpenGLFunctions::isES()) {
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
GLint oldTexture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
GLint oldTexture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
glEnable(textureTarget);
glBindTexture(textureTarget, textureId);
glEnable(textureTarget);
glBindTexture(textureTarget, textureId);
GLint textureWidth;
GLint textureHeight;
GLint textureWidth;
GLint textureHeight;
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
if (d_ptr->active_engine &&
d_ptr->active_engine->type() == QPaintEngine::OpenGL2) {
QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine);
if (!eng->isNativePaintingActive()) {
QRectF dest(point, QSizeF(textureWidth, textureHeight));
QRectF src(0, 0, textureWidth, textureHeight);
QSize size(textureWidth, textureHeight);
if (eng->drawTexture(dest, textureId, size, src))
return;
if (d_ptr->active_engine &&
d_ptr->active_engine->type() == QPaintEngine::OpenGL2) {
QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine);
if (!eng->isNativePaintingActive()) {
QRectF dest(point, QSizeF(textureWidth, textureHeight));
QRectF src(0, 0, textureWidth, textureHeight);
QSize size(textureWidth, textureHeight);
if (eng->drawTexture(dest, textureId, size, src))
return;
}
}
qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget);
if (!wasEnabled)
glDisable(textureTarget);
glBindTexture(textureTarget, oldTexture);
return;
}
qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget);
if (!wasEnabled)
glDisable(textureTarget);
glBindTexture(textureTarget, oldTexture);
#endif
qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead");
}
/*!
@ -4163,7 +4172,7 @@ void QGLWidget::glDraw()
return;
makeCurrent();
#ifndef QT_OPENGL_ES
if (d->glcx->deviceIsPixmap())
if (d->glcx->deviceIsPixmap() && !QOpenGLFunctions::isES())
glDrawBuffer(GL_FRONT);
#endif
QSize readback_target_size = d->glcx->d_ptr->readback_target_size;
@ -4206,18 +4215,20 @@ void QGLWidget::qglColor(const QColor& c) const
#ifdef QT_OPENGL_ES
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
#else
Q_D(const QGLWidget);
const QGLContext *ctx = QGLContext::currentContext();
if (ctx) {
if (ctx->format().rgba())
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
int i = d->cmap.find(c.rgb());
if (i < 0)
i = d->cmap.findNearest(c.rgb());
glIndexi(i);
} else
glIndexi(ctx->colorIndex(c));
if (!QOpenGLFunctions::isES()) {
Q_D(const QGLWidget);
const QGLContext *ctx = QGLContext::currentContext();
if (ctx) {
if (ctx->format().rgba())
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
int i = d->cmap.find(c.rgb());
if (i < 0)
i = d->cmap.findNearest(c.rgb());
glIndexi(i);
} else
glIndexi(ctx->colorIndex(c));
}
}
#endif //QT_OPENGL_ES
#else
@ -4238,18 +4249,23 @@ void QGLWidget::qglClearColor(const QColor& c) const
#ifdef QT_OPENGL_ES
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
#else
Q_D(const QGLWidget);
const QGLContext *ctx = QGLContext::currentContext();
if (ctx) {
if (ctx->format().rgba())
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
int i = d->cmap.find(c.rgb());
if (i < 0)
i = d->cmap.findNearest(c.rgb());
glClearIndex(i);
} else
glClearIndex(ctx->colorIndex(c));
if (!QOpenGLFunctions::isES()) {
Q_D(const QGLWidget);
const QGLContext *ctx = QGLContext::currentContext();
if (ctx) {
if (ctx->format().rgba())
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
int i = d->cmap.find(c.rgb());
if (i < 0)
i = d->cmap.findNearest(c.rgb());
glClearIndex(i);
} else {
glClearIndex(ctx->colorIndex(c));
}
}
} else {
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
}
#endif
}
@ -4411,72 +4427,75 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str,
void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
{
#ifndef QT_OPENGL_ES
Q_D(QGLWidget);
if (str.isEmpty() || !isValid())
if (!QOpenGLFunctions::isES()) {
Q_D(QGLWidget);
if (str.isEmpty() || !isValid())
return;
GLint view[4];
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
if (!use_scissor_testing)
glGetIntegerv(GL_VIEWPORT, &view[0]);
int width = d->glcx->device()->width();
int height = d->glcx->device()->height();
bool auto_swap = autoBufferSwap();
QPaintEngine *engine = paintEngine();
qt_save_gl_state();
QPainter *p;
bool reuse_painter = false;
if (engine->isActive()) {
reuse_painter = true;
p = engine->painter();
glDisable(GL_DEPTH_TEST);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
} else {
setAutoBufferSwap(false);
// disable glClear() as a result of QPainter::begin()
d->disable_clear_on_painter_begin = true;
p = new QPainter(this);
}
QRect viewport(view[0], view[1], view[2], view[3]);
if (!use_scissor_testing && viewport != rect()) {
// if the user hasn't set a scissor box, we set one that
// covers the current viewport
glScissor(view[0], view[1], view[2], view[3]);
glEnable(GL_SCISSOR_TEST);
} else if (use_scissor_testing) {
// use the scissor box set by the user
glEnable(GL_SCISSOR_TEST);
}
qt_gl_draw_text(p, x, y, str, font);
if (!reuse_painter) {
p->end();
delete p;
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
qt_restore_gl_state();
return;
GLint view[4];
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
if (!use_scissor_testing)
glGetIntegerv(GL_VIEWPORT, &view[0]);
int width = d->glcx->device()->width();
int height = d->glcx->device()->height();
bool auto_swap = autoBufferSwap();
QPaintEngine *engine = paintEngine();
qt_save_gl_state();
QPainter *p;
bool reuse_painter = false;
if (engine->isActive()) {
reuse_painter = true;
p = engine->painter();
glDisable(GL_DEPTH_TEST);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
} else {
setAutoBufferSwap(false);
// disable glClear() as a result of QPainter::begin()
d->disable_clear_on_painter_begin = true;
p = new QPainter(this);
}
QRect viewport(view[0], view[1], view[2], view[3]);
if (!use_scissor_testing && viewport != rect()) {
// if the user hasn't set a scissor box, we set one that
// covers the current viewport
glScissor(view[0], view[1], view[2], view[3]);
glEnable(GL_SCISSOR_TEST);
} else if (use_scissor_testing) {
// use the scissor box set by the user
glEnable(GL_SCISSOR_TEST);
}
qt_gl_draw_text(p, x, y, str, font);
if (!reuse_painter) {
p->end();
delete p;
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
qt_restore_gl_state();
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(str);
Q_UNUSED(font);
qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
#endif
qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
}
/*! \overload
@ -4503,80 +4522,83 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font)
{
#ifndef QT_OPENGL_ES
Q_D(QGLWidget);
if (str.isEmpty() || !isValid())
if (!QOpenGLFunctions::isES()) {
Q_D(QGLWidget);
if (str.isEmpty() || !isValid())
return;
bool auto_swap = autoBufferSwap();
int width = d->glcx->device()->width();
int height = d->glcx->device()->height();
GLdouble model[4 * 4], proj[4 * 4];
GLint view[4];
glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]);
glGetIntegerv(GL_VIEWPORT, &view[0]);
GLdouble win_x = 0, win_y = 0, win_z = 0;
qgluProject(x, y, z, &model[0], &proj[0], &view[0],
&win_x, &win_y, &win_z);
win_y = height - win_y; // y is inverted
QPaintEngine *engine = paintEngine();
QPainter *p;
bool reuse_painter = false;
bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
qt_save_gl_state();
if (engine->isActive()) {
reuse_painter = true;
p = engine->painter();
} else {
setAutoBufferSwap(false);
// disable glClear() as a result of QPainter::begin()
d->disable_clear_on_painter_begin = true;
p = new QPainter(this);
}
QRect viewport(view[0], view[1], view[2], view[3]);
if (!use_scissor_testing && viewport != rect()) {
glScissor(view[0], view[1], view[2], view[3]);
glEnable(GL_SCISSOR_TEST);
} else if (use_scissor_testing) {
glEnable(GL_SCISSOR_TEST);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
glOrtho(0, width, height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glAlphaFunc(GL_GREATER, 0.0);
glEnable(GL_ALPHA_TEST);
if (use_depth_testing)
glEnable(GL_DEPTH_TEST);
glTranslated(0, 0, -win_z);
qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
if (!reuse_painter) {
p->end();
delete p;
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
qt_restore_gl_state();
return;
bool auto_swap = autoBufferSwap();
int width = d->glcx->device()->width();
int height = d->glcx->device()->height();
GLdouble model[4 * 4], proj[4 * 4];
GLint view[4];
glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]);
glGetIntegerv(GL_VIEWPORT, &view[0]);
GLdouble win_x = 0, win_y = 0, win_z = 0;
qgluProject(x, y, z, &model[0], &proj[0], &view[0],
&win_x, &win_y, &win_z);
win_y = height - win_y; // y is inverted
QPaintEngine *engine = paintEngine();
QPainter *p;
bool reuse_painter = false;
bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
qt_save_gl_state();
if (engine->isActive()) {
reuse_painter = true;
p = engine->painter();
} else {
setAutoBufferSwap(false);
// disable glClear() as a result of QPainter::begin()
d->disable_clear_on_painter_begin = true;
p = new QPainter(this);
}
QRect viewport(view[0], view[1], view[2], view[3]);
if (!use_scissor_testing && viewport != rect()) {
glScissor(view[0], view[1], view[2], view[3]);
glEnable(GL_SCISSOR_TEST);
} else if (use_scissor_testing) {
glEnable(GL_SCISSOR_TEST);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
glOrtho(0, width, height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glAlphaFunc(GL_GREATER, 0.0);
glEnable(GL_ALPHA_TEST);
if (use_depth_testing)
glEnable(GL_DEPTH_TEST);
glTranslated(0, 0, -win_z);
qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
if (!reuse_painter) {
p->end();
delete p;
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
qt_restore_gl_state();
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(z);
Q_UNUSED(str);
Q_UNUSED(font);
qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
#endif
qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
}
QGLFormat QGLWidget::format() const

View File

@ -321,21 +321,23 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
d->context = new QOpenGLContext;
#if !defined(QT_OPENGL_ES)
// On desktop, request latest released version
QSurfaceFormat format;
if (!QOpenGLFunctions::isES()) {
// On desktop, request latest released version
QSurfaceFormat format;
#if defined(Q_OS_MAC)
// OS X is limited to OpenGL 3.2 Core Profile at present
// so set that here. If we use compatibility profile it
// only reports 2.x contexts.
format.setMajorVersion(3);
format.setMinorVersion(2);
format.setProfile(QSurfaceFormat::CoreProfile);
// OS X is limited to OpenGL 3.2 Core Profile at present
// so set that here. If we use compatibility profile it
// only reports 2.x contexts.
format.setMajorVersion(3);
format.setMinorVersion(2);
format.setProfile(QSurfaceFormat::CoreProfile);
#else
format.setMajorVersion(4);
format.setMinorVersion(3);
#endif
d->context->setFormat(format);
format.setMajorVersion(4);
format.setMinorVersion(3);
#endif
d->context->setFormat(format);
}
#endif // QT_OPENGL_ES
d->context->create();
d->context->makeCurrent(d->window);
}

View File

@ -344,18 +344,20 @@ void QGLBuffer::destroy()
bool QGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
Q_D(QGLBuffer);
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
return false;
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
d->funcs->glGetBufferSubData(d->type, offset, count, data);
return glGetError() == GL_NO_ERROR;
if (QOpenGLFunctions::platformGLType() != QOpenGLFunctions::GLES1) {
Q_D(QGLBuffer);
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
return false;
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
d->funcs->glGetBufferSubData(d->type, offset, count, data);
return glGetError() == GL_NO_ERROR;
}
#else
Q_UNUSED(offset);
Q_UNUSED(data);
Q_UNUSED(count);
return false;
#endif
return false;
}
/*!

View File

@ -373,8 +373,11 @@ void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f,
GLenum format = f->format().internalTextureFormat();
reqAlpha = (format != GL_RGB
#ifndef QT_OPENGL_ES
&& format != GL_RGB5 && format != GL_RGB8
#ifdef GL_RGB5
&& format != GL_RGB5
#endif
#ifdef GL_RGB8
&& format != GL_RGB8
#endif
);
}
@ -592,8 +595,17 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
GL_DEPTH_COMPONENT16, size.width(), size.height());
}
#else
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT, size.width(), size.height());
if (QOpenGLFunctions::isES()) {
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24))
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT24, size.width(), size.height());
else
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT16, size.width(), size.height());
} else {
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH_COMPONENT, size.width(), size.height());
}
#endif
} else {
#ifdef QT_OPENGL_ES
@ -605,7 +617,17 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
size.width(), size.height());
}
#else
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
if (QOpenGLFunctions::isES()) {
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
size.width(), size.height());
} else {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
size.width(), size.height());
}
} else {
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
}
#endif
}
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
@ -621,23 +643,18 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
funcs.glGenRenderbuffers(1, &stencil_buffer);
funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
#ifdef QT_OPENGL_ES
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_STENCIL_INDEX8, size.width(), size.height());
GLenum storage = GL_STENCIL_INDEX8;
#else
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_STENCIL_INDEX, size.width(), size.height());
GLenum storage = QOpenGLFunctions::isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
#endif
} else {
#ifdef QT_OPENGL_ES
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
size.width(), size.height());
#else
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
size.width(), size.height());
#endif
}
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height());
else
funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height());
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_buffer);
valid = checkFramebufferStatus();
@ -830,7 +847,13 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
d->init(this, size, NoAttachment, target,
#ifndef QT_OPENGL_ES_2
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
#else
GL_RGBA
#endif
);
}
/*! \overload
@ -844,7 +867,13 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
d->init(this, QSize(width, height), NoAttachment, target,
#ifndef QT_OPENGL_ES_2
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
#else
GL_RGBA
#endif
);
}
/*! \overload
@ -893,6 +922,12 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
if (!internal_format)
#ifdef QT_OPENGL_ES_2
internal_format = GL_RGBA;
#else
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
#endif
d->init(this, QSize(width, height), attachment, target, internal_format);
}
@ -914,6 +949,12 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
if (!internal_format)
#ifdef QT_OPENGL_ES_2
internal_format = GL_RGBA;
#else
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
#endif
d->init(this, size, attachment, target, internal_format);
}

View File

@ -63,17 +63,11 @@ public:
QGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D);
QGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D);
#if !defined(QT_OPENGL_ES) || defined(Q_QDOC)
QGLFramebufferObject(const QSize &size, Attachment attachment,
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QGLFramebufferObject(int width, int height, Attachment attachment,
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
#else
QGLFramebufferObject(const QSize &size, Attachment attachment,
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
QGLFramebufferObject(int width, int height, Attachment attachment,
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
#endif
GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format);
QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format);

View File

@ -60,12 +60,6 @@
QT_BEGIN_NAMESPACE
#ifndef QT_OPENGL_ES
#define DEFAULT_FORMAT GL_RGBA8
#else
#define DEFAULT_FORMAT GL_RGBA
#endif
class QGLFramebufferObjectFormatPrivate
{
public:
@ -74,9 +68,13 @@ public:
samples(0),
attachment(QGLFramebufferObject::NoAttachment),
target(GL_TEXTURE_2D),
internal_format(DEFAULT_FORMAT),
mipmap(false)
{
#ifndef QT_OPENGL_ES_2
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
#else
internal_format = GL_RGBA;
#endif
}
QGLFramebufferObjectFormatPrivate
(const QGLFramebufferObjectFormatPrivate *other)

View File

@ -213,94 +213,94 @@ QGLFunctions::QGLFunctions(const QGLContext *context)
static int qt_gl_resolve_features()
{
#if defined(QT_OPENGL_ES_2)
int features = QGLFunctions::Multitexture |
QGLFunctions::Shaders |
QGLFunctions::Buffers |
QGLFunctions::Framebuffers |
QGLFunctions::BlendColor |
QGLFunctions::BlendEquation |
QGLFunctions::BlendEquationSeparate |
QGLFunctions::BlendFuncSeparate |
QGLFunctions::BlendSubtract |
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample |
QGLFunctions::StencilSeparate;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_OES_texture_npot"))
features |= QGLFunctions::NPOTTextures;
if (extensions.match("GL_IMG_texture_npot"))
features |= QGLFunctions::NPOTTextures;
return features;
#elif defined(QT_OPENGL_ES)
int features = QGLFunctions::Multitexture |
QGLFunctions::Buffers |
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_OES_framebuffer_object"))
features |= QGLFunctions::Framebuffers;
if (extensions.match("GL_OES_blend_equation_separate"))
features |= QGLFunctions::BlendEquationSeparate;
if (extensions.match("GL_OES_blend_func_separate"))
features |= QGLFunctions::BlendFuncSeparate;
if (extensions.match("GL_OES_blend_subtract"))
features |= QGLFunctions::BlendSubtract;
if (extensions.match("GL_OES_texture_npot"))
features |= QGLFunctions::NPOTTextures;
if (extensions.match("GL_IMG_texture_npot"))
features |= QGLFunctions::NPOTTextures;
return features;
#else
int features = 0;
QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
QOpenGLExtensionMatcher extensions;
if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES2) {
int features = QGLFunctions::Multitexture |
QGLFunctions::Shaders |
QGLFunctions::Buffers |
QGLFunctions::Framebuffers |
QGLFunctions::BlendColor |
QGLFunctions::BlendEquation |
QGLFunctions::BlendEquationSeparate |
QGLFunctions::BlendFuncSeparate |
QGLFunctions::BlendSubtract |
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample |
QGLFunctions::StencilSeparate;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_OES_texture_npot"))
features |= QGLFunctions::NPOTTextures;
if (extensions.match("GL_IMG_texture_npot"))
features |= QGLFunctions::NPOTTextures;
return features;
} if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES1) {
int features = QGLFunctions::Multitexture |
QGLFunctions::Buffers |
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample;
QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_OES_framebuffer_object"))
features |= QGLFunctions::Framebuffers;
if (extensions.match("GL_OES_blend_equation_separate"))
features |= QGLFunctions::BlendEquationSeparate;
if (extensions.match("GL_OES_blend_func_separate"))
features |= QGLFunctions::BlendFuncSeparate;
if (extensions.match("GL_OES_blend_subtract"))
features |= QGLFunctions::BlendSubtract;
if (extensions.match("GL_OES_texture_npot"))
features |= QGLFunctions::NPOTTextures;
if (extensions.match("GL_IMG_texture_npot"))
features |= QGLFunctions::NPOTTextures;
return features;
} else {
int features = 0;
QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
QOpenGLExtensionMatcher extensions;
// Recognize features by extension name.
if (extensions.match("GL_ARB_multitexture"))
features |= QGLFunctions::Multitexture;
if (extensions.match("GL_ARB_shader_objects"))
features |= QGLFunctions::Shaders;
if (extensions.match("GL_EXT_framebuffer_object") ||
// Recognize features by extension name.
if (extensions.match("GL_ARB_multitexture"))
features |= QGLFunctions::Multitexture;
if (extensions.match("GL_ARB_shader_objects"))
features |= QGLFunctions::Shaders;
if (extensions.match("GL_EXT_framebuffer_object") ||
extensions.match("GL_ARB_framebuffer_object"))
features |= QGLFunctions::Framebuffers;
if (extensions.match("GL_EXT_blend_color"))
features |= QGLFunctions::BlendColor;
if (extensions.match("GL_EXT_blend_equation_separate"))
features |= QGLFunctions::BlendEquationSeparate;
if (extensions.match("GL_EXT_blend_func_separate"))
features |= QGLFunctions::BlendFuncSeparate;
if (extensions.match("GL_EXT_blend_subtract"))
features |= QGLFunctions::BlendSubtract;
if (extensions.match("GL_ARB_texture_compression"))
features |= QGLFunctions::CompressedTextures;
if (extensions.match("GL_ARB_multisample"))
features |= QGLFunctions::Multisample;
if (extensions.match("GL_ARB_texture_non_power_of_two"))
features |= QGLFunctions::NPOTTextures;
features |= QGLFunctions::Framebuffers;
if (extensions.match("GL_EXT_blend_color"))
features |= QGLFunctions::BlendColor;
if (extensions.match("GL_EXT_blend_equation_separate"))
features |= QGLFunctions::BlendEquationSeparate;
if (extensions.match("GL_EXT_blend_func_separate"))
features |= QGLFunctions::BlendFuncSeparate;
if (extensions.match("GL_EXT_blend_subtract"))
features |= QGLFunctions::BlendSubtract;
if (extensions.match("GL_ARB_texture_compression"))
features |= QGLFunctions::CompressedTextures;
if (extensions.match("GL_ARB_multisample"))
features |= QGLFunctions::Multisample;
if (extensions.match("GL_ARB_texture_non_power_of_two"))
features |= QGLFunctions::NPOTTextures;
// Recognize features by minimum OpenGL version.
if (versions & QGLFormat::OpenGL_Version_1_2) {
features |= QGLFunctions::BlendColor |
QGLFunctions::BlendEquation;
// Recognize features by minimum OpenGL version.
if (versions & QGLFormat::OpenGL_Version_1_2) {
features |= QGLFunctions::BlendColor |
QGLFunctions::BlendEquation;
}
if (versions & QGLFormat::OpenGL_Version_1_3) {
features |= QGLFunctions::Multitexture |
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample;
}
if (versions & QGLFormat::OpenGL_Version_1_4)
features |= QGLFunctions::BlendFuncSeparate;
if (versions & QGLFormat::OpenGL_Version_1_5)
features |= QGLFunctions::Buffers;
if (versions & QGLFormat::OpenGL_Version_2_0) {
features |= QGLFunctions::Shaders |
QGLFunctions::StencilSeparate |
QGLFunctions::BlendEquationSeparate |
QGLFunctions::NPOTTextures;
}
return features;
}
if (versions & QGLFormat::OpenGL_Version_1_3) {
features |= QGLFunctions::Multitexture |
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample;
}
if (versions & QGLFormat::OpenGL_Version_1_4)
features |= QGLFunctions::BlendFuncSeparate;
if (versions & QGLFormat::OpenGL_Version_1_5)
features |= QGLFunctions::Buffers;
if (versions & QGLFormat::OpenGL_Version_2_0) {
features |= QGLFunctions::Shaders |
QGLFunctions::StencilSeparate |
QGLFunctions::BlendEquationSeparate |
QGLFunctions::NPOTTextures;
}
return features;
#endif
}
/*!

View File

@ -51,6 +51,7 @@
#include <QtOpenGL/qgl.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qopenglfunctions.h>
QT_BEGIN_NAMESPACE

View File

@ -361,7 +361,8 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
glBindTexture(GL_TEXTURE_2D, texture_id);
#ifndef QT_OPENGL_ES
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, d->req_size.width(), d->req_size.height(), 0);
GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0);
#else
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
#endif
@ -487,7 +488,8 @@ GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target)
{
Q_D(QGLPixelBuffer);
#ifndef QT_OPENGL_ES
return d->qctx->bindTexture(image, target, GLint(GL_RGBA8));
GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
return d->qctx->bindTexture(image, target, GLint(format));
#else
return d->qctx->bindTexture(image, target, GL_RGBA);
#endif
@ -505,7 +507,8 @@ GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target)
{
Q_D(QGLPixelBuffer);
#ifndef QT_OPENGL_ES
return d->qctx->bindTexture(pixmap, target, GLint(GL_RGBA8));
GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
return d->qctx->bindTexture(pixmap, target, GLint(format));
#else
return d->qctx->bindTexture(pixmap, target, GL_RGBA);
#endif

View File

@ -47,6 +47,7 @@
#include <QtCore/qfile.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qvector.h>
#include <QDebug>
QT_BEGIN_NAMESPACE
@ -246,7 +247,8 @@ bool QGLShaderPrivate::create()
if (shaderType == QGLShader::Vertex)
shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
#if !defined(QT_OPENGL_ES_2)
else if (shaderType == QGLShader::Geometry)
else if (shaderType == QGLShader::Geometry
&& !QOpenGLFunctions::isES())
shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT);
#endif
else
@ -428,11 +430,14 @@ bool QGLShader::compileSourceCode(const char *source)
srclen.append(GLint(headerLen));
}
#ifdef QGL_DEFINE_QUALIFIERS
src.append(qualifierDefines);
srclen.append(GLint(sizeof(qualifierDefines) - 1));
if (!QOpenGLFunctions::isES()) {
src.append(qualifierDefines);
srclen.append(GLint(sizeof(qualifierDefines) - 1));
}
#endif
#ifdef QGL_REDEFINE_HIGHP
if (d->shaderType == Fragment) {
if (d->shaderType == Fragment
&& QOpenGLFunctions::isES()) {
src.append(redefineHighp);
srclen.append(GLint(sizeof(redefineHighp) - 1));
}
@ -562,13 +567,15 @@ public:
void initializeGeometryShaderFunctions()
{
QOpenGLContext *context = QOpenGLContext::currentContext();
glProgramParameteri = (type_glProgramParameteri)
context->getProcAddress("glProgramParameteri");
if (!glProgramParameteri) {
if (!QOpenGLFunctions::isES()) {
QOpenGLContext *context = QOpenGLContext::currentContext();
glProgramParameteri = (type_glProgramParameteri)
context->getProcAddress("glProgramParameteriEXT");
context->getProcAddress("glProgramParameteri");
if (!glProgramParameteri) {
glProgramParameteri = (type_glProgramParameteri)
context->getProcAddress("glProgramParameteriEXT");
}
}
}
@ -929,7 +936,8 @@ bool QGLShaderProgram::link()
#if !defined(QT_OPENGL_ES_2)
// Set up the geometry shader parameters
if (d->glfuncs->glProgramParameteri) {
if (!QOpenGLFunctions::isES()
&& d->glfuncs->glProgramParameteri) {
foreach (QGLShader *shader, d->shaders) {
if (shader->shaderType() & QGLShader::Geometry) {
d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_INPUT_TYPE_EXT,
@ -3060,7 +3068,8 @@ int QGLShaderProgram::maxGeometryOutputVertices() const
{
GLint n = 0;
#if !defined(QT_OPENGL_ES_2)
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
if (!QOpenGLFunctions::isES())
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
#endif
return n;
}

View File

@ -37,4 +37,15 @@ contains(QT_CONFIG,egl) {
$$PWD/qxlibeglintegration.cpp
}
CONFIG += egl
} else: contains(QT_CONFIG,dynamicgl) {
HEADERS += \
$$PWD/qeglconvenience_p.h \
$$PWD/qeglplatformcontext_p.h \
$$PWD/qeglpbuffer_p.h
SOURCES += \
$$PWD/qeglconvenience.cpp \
$$PWD/qeglplatformcontext.cpp \
$$PWD/qeglpbuffer.cpp
}

View File

@ -40,6 +40,7 @@
****************************************************************************/
#include <QByteArray>
#include <QOpenGLFunctions>
#ifdef Q_OS_LINUX
#include <sys/ioctl.h>
@ -243,12 +244,15 @@ EGLConfig QEglConfigChooser::chooseConfig()
configureAttributes.append(EGL_OPENVG_BIT);
break;
#ifdef EGL_VERSION_1_4
# if !defined(QT_OPENGL_ES_2)
case QSurfaceFormat::DefaultRenderableType:
# endif
case QSurfaceFormat::OpenGL:
configureAttributes.append(EGL_OPENGL_BIT);
if (!QOpenGLFunctions::isES())
configureAttributes.append(EGL_OPENGL_BIT);
else
configureAttributes.append(EGL_OPENGL_ES2_BIT);
break;
case QSurfaceFormat::OpenGL:
configureAttributes.append(EGL_OPENGL_BIT);
break;
#endif
case QSurfaceFormat::OpenGLES:
if (m_format.majorVersion() == 1) {
@ -353,11 +357,12 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config,
if (referenceFormat.renderableType() == QSurfaceFormat::OpenVG && (renderableType & EGL_OPENVG_BIT))
format.setRenderableType(QSurfaceFormat::OpenVG);
#ifdef EGL_VERSION_1_4
else if ((referenceFormat.renderableType() == QSurfaceFormat::OpenGL
# if !defined(QT_OPENGL_ES_2)
|| referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType
# endif
) && (renderableType & EGL_OPENGL_BIT))
else if (referenceFormat.renderableType() == QSurfaceFormat::OpenGL
&& (renderableType & EGL_OPENGL_BIT))
format.setRenderableType(QSurfaceFormat::OpenGL);
else if (referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType
&& !QOpenGLFunctions::isES()
&& (renderableType & EGL_OPENGL_BIT))
format.setRenderableType(QSurfaceFormat::OpenGL);
#endif
else

View File

@ -42,6 +42,7 @@
#include "qeglplatformcontext_p.h"
#include "qeglconvenience_p.h"
#include <qpa/qplatformwindow.h>
#include <QtGui/QOpenGLFunctions>
QT_BEGIN_NAMESPACE
@ -69,9 +70,12 @@ static inline void bindApi(const QSurfaceFormat &format)
eglBindAPI(EGL_OPENVG_API);
break;
#ifdef EGL_VERSION_1_4
# if !defined(QT_OPENGL_ES_2)
case QSurfaceFormat::DefaultRenderableType:
# endif
if (!QOpenGLFunctions::isES())
eglBindAPI(EGL_OPENGL_API);
else
eglBindAPI(EGL_OPENGL_ES_API);
break;
case QSurfaceFormat::OpenGL:
eglBindAPI(EGL_OPENGL_API);
break;

View File

@ -135,11 +135,7 @@ QWindowsEGLContext::~QWindowsEGLContext()
bool QWindowsEGLContext::hasThreadedOpenGLCapability()
{
#ifdef QT_OPENGL_ES_2_ANGLE
return false;
#else
return true;
#endif
}
EGLSurface QWindowsEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)

View File

@ -43,12 +43,20 @@
#include "qwindowsintegration.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
#if defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
# include "qwindowseglcontext.h"
# include <QtGui/QOpenGLContext>
#elif !defined(QT_NO_OPENGL)
#endif
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
# include "qwindowsglcontext.h"
#endif
#if !defined(QT_NO_OPENGL)
# include <QtGui/QOpenGLFunctions>
#endif
#include "qwindowsscreen.h"
#include "qwindowstheme.h"
#include "qwindowsservices.h"
@ -125,9 +133,10 @@ QT_BEGIN_NAMESPACE
struct QWindowsIntegrationPrivate
{
#if defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
typedef QSharedPointer<QWindowsEGLStaticContext> QEGLStaticContextPtr;
#elif !defined(QT_NO_OPENGL)
#endif
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
#endif
@ -143,9 +152,10 @@ struct QWindowsIntegrationPrivate
QWindowsDrag m_drag;
# endif
#endif
#if defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
QEGLStaticContextPtr m_staticEGLContext;
#elif !defined(QT_NO_OPENGL)
#endif
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
QOpenGLStaticContextPtr m_staticOpenGLContext;
#endif
QWindowsInputContext m_inputContext;
@ -216,8 +226,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
case OpenGL:
return true;
case ThreadedOpenGL:
# ifdef QT_OPENGL_ES_2
return QWindowsEGLContext::hasThreadedOpenGLCapability();
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
return QOpenGLFunctions::isES() ? QWindowsEGLContext::hasThreadedOpenGLCapability() : true;
# else
return true;
# endif // QT_OPENGL_ES_2
@ -278,23 +288,27 @@ QPlatformOpenGLContext
*QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
qCDebug(lcQpaGl) << __FUNCTION__ << context->format();
#ifdef QT_OPENGL_ES_2
if (d->m_staticEGLContext.isNull()) {
QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create();
if (!staticContext)
return 0;
d->m_staticEGLContext = QSharedPointer<QWindowsEGLStaticContext>(staticContext);
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
if (QOpenGLFunctions::isES()){
if (d->m_staticEGLContext.isNull()) {
QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create();
if (!staticContext)
return 0;
d->m_staticEGLContext = QSharedPointer<QWindowsEGLStaticContext>(staticContext);
}
return new QWindowsEGLContext(d->m_staticEGLContext, context->format(), context->shareHandle());
}
#endif
#if !defined(QT_OPENGL_ES_2)
if (!QOpenGLFunctions::isES()) {
if (d->m_staticOpenGLContext.isNull())
d->m_staticOpenGLContext =
QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
return result->isValid() ? result.take() : 0;
}
return new QWindowsEGLContext(d->m_staticEGLContext, context->format(), context->shareHandle());
#else // QT_OPENGL_ES_2
if (d->m_staticOpenGLContext.isNull())
d->m_staticOpenGLContext =
QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
if (result->isValid())
return result.take();
return 0;
#endif // !QT_OPENGL_ES_2
return 0;
}
#endif // !QT_NO_OPENGL

View File

@ -43,13 +43,19 @@
#include "qwindowswindow.h"
#include "qwindowscontext.h"
#if defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
# include "qwindowseglcontext.h"
# include <QtGui/QOpenGLContext>
#elif !defined(QT_NO_OPENGL)
#endif
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
# include "qwindowsglcontext.h"
#endif
#if !defined(QT_NO_OPENGL)
# include <QtGui/QOpenGLFunctions>
#endif
#include <QtGui/QWindow>
QT_BEGIN_NAMESPACE
@ -113,19 +119,24 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour
qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
return 0;
}
#ifdef QT_OPENGL_ES_2
QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle());
if (resource == QByteArrayLiteral("eglDisplay"))
return windowsEglContext->eglDisplay();
if (resource == QByteArrayLiteral("eglContext"))
return windowsEglContext->eglContext();
if (resource == QByteArrayLiteral("eglConfig"))
return windowsEglContext->eglConfig();
#else // QT_OPENGL_ES_2
QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
if (resource == QByteArrayLiteral("renderingContext"))
return windowsContext->renderingContext();
#endif // !QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
if (QOpenGLFunctions::isES()) {
QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle());
if (resource == QByteArrayLiteral("eglDisplay"))
return windowsEglContext->eglDisplay();
if (resource == QByteArrayLiteral("eglContext"))
return windowsEglContext->eglContext();
if (resource == QByteArrayLiteral("eglConfig"))
return windowsEglContext->eglConfig();
}
#endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC
#if !defined(QT_OPENGL_ES_2)
if (!QOpenGLFunctions::isES()) {
QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
if (resource == QByteArrayLiteral("renderingContext"))
return windowsContext->renderingContext();
}
#endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC
qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
return 0;

View File

@ -48,8 +48,9 @@
# include "qwindowscursor.h"
#endif
#ifdef QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
# include "qwindowseglcontext.h"
# include <QtGui/QOpenGLFunctions>
#endif
#include <QtGui/QGuiApplication>
@ -861,7 +862,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
m_dropTarget(0),
m_savedStyle(0),
m_format(aWindow->format()),
#ifdef QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
m_eglSurface(0),
#endif
#ifdef Q_OS_WINCE
@ -878,8 +879,9 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
return; // No further handling for Qt::Desktop
if (aWindow->surfaceType() == QWindow::OpenGLSurface) {
setFlag(OpenGLSurface);
#ifdef QT_OPENGL_ES_2
setFlag(OpenGL_ES2);
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
if (QOpenGLFunctions::isES())
setFlag(OpenGL_ES2);
#endif
}
updateDropSite();
@ -933,7 +935,7 @@ void QWindowsWindow::destroyWindow()
if (hasMouseCapture())
setMouseGrabEnabled(false);
setDropSiteEnabled(false);
#ifdef QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
if (m_eglSurface) {
qCDebug(lcQpaGl) << __FUNCTION__ << "Freeing EGL surface " << m_eglSurface << window();
eglDestroySurface(m_staticEglContext->display(), m_eglSurface);
@ -2107,7 +2109,7 @@ void QWindowsWindow::setEnabled(bool enabled)
setStyle(newStyle);
}
#ifdef QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
EGLSurface QWindowsWindow::ensureEglSurfaceHandle(const QWindowsWindow::QWindowsEGLStaticContextPtr &staticContext, EGLConfig config)
{
if (!m_eglSurface) {

View File

@ -50,7 +50,7 @@
#include <qpa/qplatformwindow.h>
#ifdef QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
# include <QtCore/QSharedPointer>
# include <EGL/egl.h>
#endif
@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class QWindowsOleDropTarget;
class QDebug;
#ifdef QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
class QWindowsEGLStaticContext;
#endif
@ -130,7 +130,7 @@ struct QWindowsWindowData
class QWindowsWindow : public QPlatformWindow
{
public:
#ifdef QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
typedef QSharedPointer<QWindowsEGLStaticContext> QWindowsEGLStaticContextPtr;
#endif
@ -206,7 +206,7 @@ public:
QMargins customMargins() const { return m_data.customMargins; }
void setCustomMargins(const QMargins &m);
#ifdef QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
EGLSurface eglSurfaceHandle() const { return m_eglSurface;}
EGLSurface ensureEglSurfaceHandle(const QWindowsEGLStaticContextPtr &staticContext, EGLConfig config);
#endif
@ -301,7 +301,7 @@ private:
unsigned m_savedStyle;
QRect m_savedFrameGeometry;
const QSurfaceFormat m_format;
#ifdef QT_OPENGL_ES_2
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
EGLSurface m_eglSurface;
QSharedPointer<QWindowsEGLStaticContext> m_staticEglContext;
#endif

View File

@ -2,7 +2,7 @@
LIBS *= -lole32
!wince*:LIBS *= -luser32 -lwinspool -limm32 -lwinmm -loleaut32
contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):LIBS *= -lopengl32
contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):!contains(QT_CONFIG, dynamicgl): LIBS *= -lopengl32
mingw: LIBS *= -luuid
# For the dialog helpers:
@ -71,11 +71,15 @@ INCLUDEPATH += $$PWD
contains(QT_CONFIG, opengles2) {
SOURCES += $$PWD/qwindowseglcontext.cpp
HEADERS += $$PWD/qwindowseglcontext.h
} else {
contains(QT_CONFIG, opengl) {
SOURCES += $$PWD/qwindowsglcontext.cpp
HEADERS += $$PWD/qwindowsglcontext.h
}
} else: contains(QT_CONFIG,opengl) {
SOURCES += $$PWD/qwindowsglcontext.cpp
HEADERS += $$PWD/qwindowsglcontext.h
}
# Dynamic GL needs both WGL and EGL
contains(QT_CONFIG,dynamicgl) {
SOURCES += $$PWD/qwindowseglcontext.cpp
HEADERS += $$PWD/qwindowseglcontext.h
}
!contains( DEFINES, QT_NO_CLIPBOARD ) {

View File

@ -130,7 +130,7 @@ contains(QT_CONFIG, dbus) {
}
contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent
!contains(QT_CONFIG, no-gui) {
win32:contains(QT_CONFIG, angle) {
win32:contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
SUBDIRS += src_angle
src_gui.depends += src_angle
}

View File

@ -49,6 +49,7 @@
#include <qglframebufferobject.h>
#include <qglcolormap.h>
#include <qpaintengine.h>
#include <qopenglfunctions.h>
#include <QGraphicsView>
#include <QGraphicsProxyWidget>
@ -751,7 +752,10 @@ void tst_QGL::openGLVersionCheck()
#elif defined(QT_OPENGL_ES_2)
QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0);
#else
QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1);
if (QOpenGLFunctions::isES())
QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0);
else
QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1);
#endif //defined(QT_OPENGL_ES_1)
}
#endif //QT_BUILD_INTERNAL
@ -1511,12 +1515,6 @@ void tst_QGL::colormap()
QCOMPARE(cmap4.size(), 256);
}
#ifndef QT_OPENGL_ES
#define DEFAULT_FORMAT GL_RGBA8
#else
#define DEFAULT_FORMAT GL_RGBA
#endif
#ifndef GL_TEXTURE_3D
#define GL_TEXTURE_3D 0x806F
#endif
@ -1532,7 +1530,13 @@ void tst_QGL::fboFormat()
QCOMPARE(format1.samples(), 0);
QVERIFY(format1.attachment() == QGLFramebufferObject::NoAttachment);
QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_2D));
QCOMPARE(int(format1.internalTextureFormat()), int(DEFAULT_FORMAT));
int expectedFormat =
#ifdef QT_OPENGL_ES_2
GL_RGBA;
#else
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
#endif
QCOMPARE(int(format1.internalTextureFormat()), expectedFormat);
// Modify the values and re-check.
format1.setSamples(8);
@ -1603,14 +1607,26 @@ void tst_QGL::fboFormat()
QGLFramebufferObjectFormat format4c;
QVERIFY(format1c == format3c);
QVERIFY(!(format1c != format3c));
format3c.setInternalTextureFormat(DEFAULT_FORMAT);
format3c.setInternalTextureFormat(
#ifdef QT_OPENGL_ES_2
GL_RGBA
#else
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
#endif
);
QVERIFY(!(format1c == format3c));
QVERIFY(format1c != format3c);
format4c = format1c;
QVERIFY(format1c == format4c);
QVERIFY(!(format1c != format4c));
format4c.setInternalTextureFormat(DEFAULT_FORMAT);
format4c.setInternalTextureFormat(
#ifdef QT_OPENGL_ES_2
GL_RGBA
#else
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
#endif
);
QVERIFY(!(format1c == format4c));
QVERIFY(format1c != format4c);
}

View File

@ -96,97 +96,99 @@ void tst_QGLFunctions::features()
funcs.initializeGLFunctions();
// Validate the features against what we expect for this platform.
#if defined(QT_OPENGL_ES_2)
QGLFunctions::OpenGLFeatures allFeatures =
(QGLFunctions::Multitexture |
QGLFunctions::Shaders |
QGLFunctions::Buffers |
QGLFunctions::Framebuffers |
QGLFunctions::BlendColor |
QGLFunctions::BlendEquation |
QGLFunctions::BlendEquationSeparate |
QGLFunctions::BlendFuncSeparate |
QGLFunctions::BlendSubtract |
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample |
QGLFunctions::StencilSeparate |
QGLFunctions::NPOTTextures);
QVERIFY((funcs.openGLFeatures() & allFeatures) == allFeatures);
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Shaders));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures));
#elif defined(QT_OPENGL_ES)
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
if (QOpenGLFunctions::isES()) {
#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2)
QGLFunctions::OpenGLFeatures allFeatures =
(QGLFunctions::Multitexture |
QGLFunctions::Shaders |
QGLFunctions::Buffers |
QGLFunctions::Framebuffers |
QGLFunctions::BlendColor |
QGLFunctions::BlendEquation |
QGLFunctions::BlendEquationSeparate |
QGLFunctions::BlendFuncSeparate |
QGLFunctions::BlendSubtract |
QGLFunctions::CompressedTextures |
QGLFunctions::Multisample |
QGLFunctions::StencilSeparate |
QGLFunctions::NPOTTextures);
QVERIFY((funcs.openGLFeatures() & allFeatures) == allFeatures);
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Shaders));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures));
#elif defined(QT_OPENGL_ES) && !defined(QT_OPENGL_ES_2)
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders));
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders));
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
hasExtension("GL_OES_framebuffer_object"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
hasExtension("GL_OES_blend_equation_separate"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
hasExtension("GL_OES_blend_func_separate"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
hasExtension("GL_OES_blend_subtract"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
hasExtension("GL_OES_texture_npot"));
#else
// We check for both the extension name and the minimum OpenGL version
// for the feature. This will help us catch situations where a platform
// doesn't list an extension by name but does have the feature by virtue
// of its version number.
QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multitexture),
hasExtension("GL_ARB_multitexture") ||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Shaders),
hasExtension("GL_ARB_shader_objects") ||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Buffers),
(versions & QGLFormat::OpenGL_Version_1_5) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
hasExtension("GL_EXT_framebuffer_object") ||
hasExtension("GL_ARB_framebuffer_object"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendColor),
hasExtension("GL_EXT_blend_color") ||
(versions & QGLFormat::OpenGL_Version_1_2) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation),
(versions & QGLFormat::OpenGL_Version_1_2) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
hasExtension("GL_EXT_blend_equation_separate") ||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
hasExtension("GL_EXT_blend_func_separate") ||
(versions & QGLFormat::OpenGL_Version_1_4) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
hasExtension("GL_EXT_blend_subtract"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures),
hasExtension("GL_ARB_texture_compression") ||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multisample),
hasExtension("GL_ARB_multisample") ||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate),
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
hasExtension("GL_ARB_texture_non_power_of_two") ||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
hasExtension("GL_OES_framebuffer_object"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
hasExtension("GL_OES_blend_equation_separate"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
hasExtension("GL_OES_blend_func_separate"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
hasExtension("GL_OES_blend_subtract"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
hasExtension("GL_OES_texture_npot"));
#endif
} else {
// We check for both the extension name and the minimum OpenGL version
// for the feature. This will help us catch situations where a platform
// doesn't list an extension by name but does have the feature by virtue
// of its version number.
QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multitexture),
hasExtension("GL_ARB_multitexture") ||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Shaders),
hasExtension("GL_ARB_shader_objects") ||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Buffers),
(versions & QGLFormat::OpenGL_Version_1_5) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
hasExtension("GL_EXT_framebuffer_object") ||
hasExtension("GL_ARB_framebuffer_object"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendColor),
hasExtension("GL_EXT_blend_color") ||
(versions & QGLFormat::OpenGL_Version_1_2) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation),
(versions & QGLFormat::OpenGL_Version_1_2) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
hasExtension("GL_EXT_blend_equation_separate") ||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
hasExtension("GL_EXT_blend_func_separate") ||
(versions & QGLFormat::OpenGL_Version_1_4) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
hasExtension("GL_EXT_blend_subtract"));
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures),
hasExtension("GL_ARB_texture_compression") ||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multisample),
hasExtension("GL_ARB_multisample") ||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate),
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
hasExtension("GL_ARB_texture_non_power_of_two") ||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
}
}
// Verify that the multitexture functions appear to resolve and work.

View File

@ -333,52 +333,55 @@ static inline float qrandom() { return (rand() % 100) / 100.f; }
void renderAScene(int w, int h)
{
#ifdef QT_OPENGL_ES_2
Q_UNUSED(w)
Q_UNUSED(h)
QGLShaderProgram program;
program.addShaderFromSourceCode(QGLShader::Vertex, "attribute highp vec2 pos; void main() { gl_Position = vec4(pos.xy, 1.0, 1.0); }");
program.addShaderFromSourceCode(QGLShader::Fragment, "uniform lowp vec4 color; void main() { gl_FragColor = color; }");
program.bindAttributeLocation("pos", 0);
program.bind();
if (QOpenGLFunctions::isES()) {
QGLFunctions funcs(QGLContext::currentContext());
Q_UNUSED(w);
Q_UNUSED(h);
QGLShaderProgram program;
program.addShaderFromSourceCode(QGLShader::Vertex, "attribute highp vec2 pos; void main() { gl_Position = vec4(pos.xy, 1.0, 1.0); }");
program.addShaderFromSourceCode(QGLShader::Fragment, "uniform lowp vec4 color; void main() { gl_FragColor = color; }");
program.bindAttributeLocation("pos", 0);
program.bind();
glEnableVertexAttribArray(0);
funcs.glEnableVertexAttribArray(0);
for (int i=0; i<1000; ++i) {
GLfloat pos[] = {
(rand() % 100) / 100.f,
(rand() % 100) / 100.f,
(rand() % 100) / 100.f,
(rand() % 100) / 100.f,
(rand() % 100) / 100.f,
(rand() % 100) / 100.f
};
for (int i=0; i<1000; ++i) {
GLfloat pos[] = {
(rand() % 100) / 100.f,
(rand() % 100) / 100.f,
(rand() % 100) / 100.f,
(rand() % 100) / 100.f,
(rand() % 100) / 100.f,
(rand() % 100) / 100.f
};
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
}
#else
glViewport(0, 0, w, h);
funcs.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
}
} else {
#ifndef QT_OPENGL_ES_2
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(0, w, h, 0, 1, 100);
glTranslated(0, 0, -1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(0, w, h, 0, 1, 100);
glTranslated(0, 0, -1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
for (int i=0;i<1000; ++i) {
glBegin(GL_TRIANGLES);
glColor3f(qrandom(), qrandom(), qrandom());
glVertex2f(qrandom() * w, qrandom() * h);
glColor3f(qrandom(), qrandom(), qrandom());
glVertex2f(qrandom() * w, qrandom() * h);
glColor3f(qrandom(), qrandom(), qrandom());
glVertex2f(qrandom() * w, qrandom() * h);
glEnd();
}
for (int i=0;i<1000; ++i) {
glBegin(GL_TRIANGLES);
glColor3f(qrandom(), qrandom(), qrandom());
glVertex2f(qrandom() * w, qrandom() * h);
glColor3f(qrandom(), qrandom(), qrandom());
glVertex2f(qrandom() * w, qrandom() * h);
glColor3f(qrandom(), qrandom(), qrandom());
glVertex2f(qrandom() * w, qrandom() * h);
glEnd();
}
#endif
}
}
class ThreadSafeGLWidget : public QGLWidget

View File

@ -2596,8 +2596,8 @@ void tst_QMdiArea::nativeSubWindows()
const QString platformName = QGuiApplication::platformName();
if (platformName != QLatin1String("xcb") && platformName != QLatin1String("windows"))
QSKIP(qPrintable(QString::fromLatin1("nativeSubWindows() does not work on this platform (%1).").arg(platformName)));
#ifdef QT_OPENGL_ES_2_ANGLE
if (platformName == QLatin1String("windows"))
#ifdef Q_OS_WIN
if (QOpenGLFunctions::isES())
QSKIP("nativeSubWindows() does not work with ANGLE on Windows, QTBUG-28545.");
#endif
{ // Add native widgets after show.

View File

@ -259,6 +259,7 @@ Configure::Configure(int& argc, char** argv)
dictionary[ "ICU" ] = "auto";
dictionary[ "ANGLE" ] = "auto";
dictionary[ "DYNAMICGL" ] = "auto";
dictionary[ "GIF" ] = "auto";
dictionary[ "JPEG" ] = "auto";
@ -682,6 +683,8 @@ void Configure::parseCmdLine()
dictionary[ "OPENGL_ES_2" ] = "yes";
} else if ( configCmdLine.at(i) == "desktop" ) {
// OPENGL=yes suffices
} else if ( configCmdLine.at(i) == "dynamic" ) {
dictionary[ "DYNAMICGL" ] = "yes";
} else {
cout << "Argument passed to -opengl option is not valid." << endl;
dictionary[ "DONE" ] = "error";
@ -1623,6 +1626,7 @@ void Configure::applySpecSpecifics()
dictionary[ "CE_CRT" ] = "yes";
dictionary[ "LARGE_FILE" ] = "no";
dictionary[ "ANGLE" ] = "d3d11";
dictionary[ "DYNAMICGL" ] = "no";
if (dictionary.value("XQMAKESPEC").startsWith("winphone"))
dictionary[ "SQL_SQLITE" ] = "no";
} else if (dictionary.value("XQMAKESPEC").startsWith("wince")) {
@ -1645,6 +1649,7 @@ void Configure::applySpecSpecifics()
dictionary[ "CE_CRT" ] = "yes";
dictionary[ "LARGE_FILE" ] = "no";
dictionary[ "ANGLE" ] = "no";
dictionary[ "DYNAMICGL" ] = "no";
// We only apply MMX/IWMMXT for mkspecs we know they work
if (dictionary[ "XQMAKESPEC" ].startsWith("wincewm")) {
dictionary[ "MMX" ] = "yes";
@ -1674,6 +1679,7 @@ void Configure::applySpecSpecifics()
dictionary["LGMON"] = "auto";
dictionary["QT_XKBCOMMON"] = "no";
dictionary[ "ANGLE" ] = "no";
dictionary[ "DYNAMICGL" ] = "no";
dictionary[ "FONT_CONFIG" ] = "auto";
} else if (platform() == ANDROID) {
dictionary[ "REDUCE_EXPORTS" ] = "yes";
@ -1681,6 +1687,7 @@ void Configure::applySpecSpecifics()
dictionary[ "BUILDALL" ] = "no";
dictionary[ "LARGE_FILE" ] = "no";
dictionary[ "ANGLE" ] = "no";
dictionary[ "DYNAMICGL" ] = "no";
dictionary[ "REDUCE_RELOCATIONS" ] = "yes";
dictionary[ "QT_GETIFADDRS" ] = "no";
dictionary[ "QT_XKBCOMMON" ] = "no";
@ -1792,9 +1799,10 @@ bool Configure::displayHelp()
desc("OPENGL", "no","-no-opengl", "Do not support OpenGL.");
desc("OPENGL", "no","-opengl <api>", "Enable OpenGL support with specified API version.\n"
"Available values for <api>:");
desc("", "no", "", " desktop - Enable support for Desktop OpenGL", ' ');
desc("", "no", "", " desktop - Enable support for Desktop OpenGL", ' ');
desc("", "no", "", " dynamic - Enable support for dynamically loaded OpenGL (either desktop or ES)", ' ');
desc("OPENGL_ES_CM", "no", "", " es1 - Enable support for OpenGL ES Common Profile", ' ');
desc("OPENGL_ES_2", "yes", "", " es2 - Enable support for OpenGL ES 2.0\n", ' ');
desc("OPENGL_ES_2", "yes", "", " es2 - Enable support for OpenGL ES 2.0\n", ' ');
desc("OPENVG", "no","-no-openvg", "Disables OpenVG functionality.");
desc("OPENVG", "yes","-openvg", "Enables OpenVG functionality.\n");
@ -2299,6 +2307,10 @@ void Configure::autoDetection()
}
}
// Dynamic GL. This must be explicitly requested, no autodetection.
if (dictionary["DYNAMICGL"] == "auto")
dictionary["DYNAMICGL"] = "no";
// Image format detection
if (dictionary["GIF"] == "auto")
dictionary["GIF"] = defaultTo("GIF");
@ -2503,6 +2515,13 @@ bool Configure::verifyConfiguration()
}
}
if (dictionary["DYNAMICGL"] == "yes") {
if (dictionary["OPENGL_ES_2"] == "yes" || dictionary["ANGLE"] != "no") {
cout << "ERROR: Dynamic OpenGL cannot be used together with native Angle (GLES2) builds." << endl;
dictionary[ "DONE" ] = "error";
}
}
if (prompt)
promptKeyPress();
@ -2580,6 +2599,10 @@ void Configure::generateOutputVars()
qmakeConfig += "angle_d3d11";
}
// Dynamic OpenGL loading ---------------------------------------
if (dictionary[ "DYNAMICGL" ] != "no")
qtConfig += "dynamicgl";
// Image formates -----------------------------------------------
if (dictionary[ "GIF" ] == "no")
qtConfig += "no-gif";
@ -3460,6 +3483,7 @@ void Configure::generateConfigfiles()
if (dictionary["OPENGL_ES_CM"] == "yes") qconfigList += "QT_OPENGL_ES_1";
if (dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES_2";
if (dictionary["DYNAMICGL"] == "yes") qconfigList += "QT_OPENGL_DYNAMIC";
if (dictionary["SQL_MYSQL"] == "yes") qconfigList += "QT_SQL_MYSQL";
if (dictionary["SQL_ODBC"] == "yes") qconfigList += "QT_SQL_ODBC";
if (dictionary["SQL_OCI"] == "yes") qconfigList += "QT_SQL_OCI";
@ -3641,6 +3665,7 @@ void Configure::displayConfig()
sout << " LGMON support..........." << dictionary[ "LGMON" ] << endl;
}
sout << " ANGLE..................." << dictionary[ "ANGLE" ] << endl;
sout << " Dynamic OpenGL.........." << dictionary[ "DYNAMICGL" ] << endl;
sout << endl;
sout << "Styles:" << endl;