Get rid of OpenGL 1.x engine and platform code from QtOpenGL.

Change-Id: I646b8e26d5e7214432a044866764d57cc11b2390
Reviewed-on: http://codereview.qt.nokia.com/3006
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
This commit is contained in:
Samuel Rødal 2011-08-16 12:53:04 +02:00 committed by Jørgen Lind
parent 06f6b71ba4
commit 0d5170256c
46 changed files with 63 additions and 16422 deletions

93
configure vendored
View File

@ -1379,9 +1379,9 @@ while [ "$#" -gt 0 ]; do
opengl)
if [ "$VAL" = "auto" ] || [ "$VAL" = "desktop" ] ||
[ "$VAL" = "yes" ] || [ "$VAL" = "no" ] ||
[ "$VAL" = "es1" ] || [ "$VAL" = "es2" ]; then
[ "$VAL" = "es2" ]; then
CFG_OPENGL="$VAL"
if [ "$VAL" = "es1" ] || [ "$VAL" = "es2" ]; then
if [ "$VAL" = "es2" ]; then
CFG_EGL="yes"
fi
else
@ -4172,9 +4172,9 @@ Qt/X11 only:
+ -opengl <api> ...... Enable OpenGL support.
With no parameter, this will auto-detect the "best"
OpenGL API to use. If desktop OpenGL is available, it
will be used. Use desktop, es1, or es2 for <api>
to force the use of the Desktop (OpenGL 1.x or 2.x),
OpenGL ES 1.x Common profile, or 2.x APIs instead.
will be used. Use desktop or es2 for <api>
to force the use of the Desktop OpenGL or
OpenGL ES 2 APIs instead.
-no-openvg ........ Do not support OpenVG.
+ -openvg ........... Enable OpenVG support.
@ -4334,9 +4334,9 @@ if [ "$PLATFORM_QWS" = "yes" -o "$PLATFORM_QPA" = "yes" ]; then
-no-opengl .......... Do not support OpenGL.
-opengl <api> ....... Enable OpenGL ES support
With no parameter, this will attempt to auto-detect OpenGL ES 1.x
or 2.x, or regular desktop OpenGL.
Use es1 or es2 for <api> to override auto-detection.
With no parameter, this will attempt to auto-detect
OpenGL ES 2, or regular desktop OpenGL.
Use es2 for <api> to override auto-detection.
EOF
fi
@ -5787,7 +5787,7 @@ fi
# X11/MINGW/SYMBIAN OpenGL
if [ "$PLATFORM_X11" = "yes" -o "$XPLATFORM_MINGW" = "yes" -o "$XPLATFORM_SYMBIAN" = "yes" ]; then
# auto-detect OpenGL support (es1 = OpenGL ES 1.x Common, es2 = OpenGL ES 2.x)
# auto-detect OpenGL support (es2 = OpenGL ES 2.x)
if [ "$CFG_GUI" = "no" ]; then
if [ "$CFG_OPENGL" = "auto" ]; then
CFG_OPENGL=no
@ -5806,11 +5806,6 @@ if [ "$PLATFORM_X11" = "yes" -o "$XPLATFORM_MINGW" = "yes" -o "$XPLATFORM_SYMBIA
if [ "$CFG_EGL" = "no" ]; then
CFG_EGL=auto
fi
elif "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles1 "OpenGL ES 1.x" $L_FLAGS $I_FLAGS $l_FLAGS; then
CFG_OPENGL=es1
if [ "$CFG_EGL" = "no" ]; then
CFG_EGL=auto
fi
else
if [ "$CFG_OPENGL" = "yes" ]; then
echo "All the OpenGL functionality tests failed!"
@ -5834,16 +5829,6 @@ if [ "$PLATFORM_X11" = "yes" -o "$XPLATFORM_MINGW" = "yes" -o "$XPLATFORM_SYMBIA
*)
;;
esac
elif [ "$CFG_OPENGL" = "es1" ]; then
# OpenGL ES 1.x
"$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles1 "OpenGL ES 1.x" $L_FLAGS $I_FLAGS $l_FLAGS
if [ $? != "0" ]; then
echo "The OpenGL ES 1.x functionality test failed!"
echo " You might need to modify the include and library search paths by editing"
echo " QMAKE_INCDIR_OPENGL_ES1, QMAKE_LIBDIR_OPENGL_ES1 and QMAKE_LIBS_OPENGL_ES1 in"
echo " ${XQMAKESPEC}."
exit 1
fi
elif [ "$CFG_OPENGL" = "es2" ]; then
#OpenGL ES 2.x
"$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS
@ -6176,7 +6161,7 @@ fi
if [ "$PLATFORM_QPA" = "yes" ]; then
# auto-detect OpenGL support (es1 = OpenGL ES 1.x Common, es2 = OpenGL ES 2.x)
# auto-detect OpenGL support (es2 = OpenGL ES 2.x)
if [ "$CFG_ARCH" = "macosx" ]; then
CFG_OPENGL=desktop
elif [ "$CFG_OPENGL" = "auto" ] || [ "$CFG_OPENGL" = "yes" ]; then
@ -6184,8 +6169,6 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
CFG_OPENGL=desktop
elif "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS; then
CFG_OPENGL=es2
elif "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles1 "OpenGL ES 1.x" $L_FLAGS $I_FLAGS $l_FLAGS; then
CFG_OPENGL=es1
else
if [ "$CFG_OPENGL" = "yes" ]; then
echo "All the OpenGL functionality tests failed!"
@ -6196,16 +6179,6 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
fi
CFG_OPENGL=no
fi
elif [ "$CFG_OPENGL" = "es1" ]; then
# OpenGL ES 1.x
"$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles1 "OpenGL ES 1.x" $L_FLAGS $I_FLAGS $l_FLAGS
if [ $? != "0" ]; then
echo "The OpenGL ES 1.x functionality test failed!"
echo " You might need to modify the include and library search paths by editing"
echo " QMAKE_INCDIR_OPENGL_ES1, QMAKE_LIBDIR_OPENGL_ES1 and QMAKE_LIBS_OPENGL_ES1 in"
echo " ${XQMAKESPEC}."
exit 1
fi
elif [ "$CFG_OPENGL" = "es2" ]; then
#OpenGL ES 2.x
if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists glesv2 2>/dev/null; then
@ -6327,7 +6300,7 @@ fi
# QWS
if [ "$PLATFORM_QWS" = "yes" ]; then
# auto-detect OpenGL support (es1 = OpenGL ES 1.x Common, es2 = OpenGL ES 2.x)
# auto-detect OpenGL support (es2 = OpenGL ES 2.x)
if [ "$CFG_GUI" = "no" ]; then
if [ "$CFG_OPENGL" = "auto" ]; then
CFG_OPENGL=no
@ -6342,26 +6315,6 @@ if [ "$PLATFORM_QWS" = "yes" ]; then
CFG_EGL=auto
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS; then
CFG_OPENGL=es2
elif "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles1 "OpenGL ES 1.x" $L_FLAGS $I_FLAGS $l_FLAGS; then
CFG_OPENGL=es1
else
echo "All the OpenGL ES functionality tests failed!"
echo " You might need to modify the include and library search paths by editing"
echo " QMAKE_INCDIR_OPENGL, QMAKE_LIBDIR_OPENGL and QMAKE_LIBS_OPENGL in"
echo " ${XQMAKESPEC}."
exit 1
fi
elif [ "$CFG_OPENGL" = "es1" ]; then
# OpenGL ES 1.x
"$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles1 "OpenGL ES 1.x" $L_FLAGS $I_FLAGS $l_FLAGS
if [ $? != "0" ]; then
echo "The OpenGL ES 1.x functionality test failed!"
echo " You might need to modify the include and library search paths by editing"
echo " QMAKE_INCDIR_OPENGL, QMAKE_LIBDIR_OPENGL and QMAKE_LIBS_OPENGL in"
echo " ${XQMAKESPEC}."
exit 1
fi
CFG_EGL=yes
elif [ "$CFG_OPENGL" = "es2" ]; then
#OpenGL ES 2.x
"$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/opengles2 "OpenGL ES 2.x" $L_FLAGS $I_FLAGS $l_FLAGS
@ -6471,16 +6424,6 @@ if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QWS" = "yes" ]; then
CFG_EGL=yes
fi
# Prefer this variant for ES1
if [ "$CFG_OPENGL" = "es1" -o "$EGL_VARIANT" = "none" ]; then
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" "config.tests/unix/egl4gles1" "EGL (GLES/egl.h)" $L_FLAGS $I_FLAGS $l_FLAGS; then
# EGL specified by QMAKE_*_EGL, included with <GLES/egl.h>
EGL_VARIANT=gles
CFG_EGL=yes
CFG_EGL_GLES_INCLUDES=yes
fi
fi
if [ "$EGL_VARIANT" = "none" ]; then
if [ "$CFG_EGL" = "yes" ]; then
echo "The EGL functionality test failed!"
@ -6492,7 +6435,7 @@ if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QWS" = "yes" ]; then
fi
CFG_EGL=no
# If QtOpenGL would be built against OpenGL ES, disable it as we can't to that if EGL is missing
if [ "$CFG_OPENGL" = "es1" -o "$CFG_OPENGL" = "es2" ]; then
if [ "$CFG_OPENGL" = "es2" ]; then
CFG_OPENGL=no
fi
fi
@ -7050,18 +6993,10 @@ else
QT_CONFIG="$QT_CONFIG opengl"
fi
if [ "$CFG_OPENGL" = "es1" ] || [ "$CFG_OPENGL" = "es2" ]; then
if [ "$PLATFORM_QWS" = "yes" ]; then
QCONFIG_FLAGS="$QCONFIG_FLAGS Q_BACKINGSTORE_SUBSURFACES"
fi
if [ "$CFG_OPENGL" = "es2" ]; then
QCONFIG_FLAGS="$QCONFIG_FLAGS QT_OPENGL_ES"
fi
if [ "$CFG_OPENGL" = "es1" ]; then
QCONFIG_FLAGS="$QCONFIG_FLAGS QT_OPENGL_ES_1"
QT_CONFIG="$QT_CONFIG opengles1"
fi
if [ "$CFG_OPENGL" = "es2" ]; then
QCONFIG_FLAGS="$QCONFIG_FLAGS QT_OPENGL_ES_2"
QT_CONFIG="$QT_CONFIG opengles2"
@ -8765,8 +8700,6 @@ if [ "$PLATFORM_QWS" = "yes" ]; then
fi
if [ "$CFG_OPENGL" = "desktop" ]; then
echo "OpenGL support ......... yes (Desktop OpenGL)"
elif [ "$CFG_OPENGL" = "es1" ]; then
echo "OpenGL support ......... yes (OpenGL ES 1.x Common profile)"
elif [ "$CFG_OPENGL" = "es2" ]; then
echo "OpenGL support ......... yes (OpenGL ES 2.x)"
else

View File

@ -1,139 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtWidgets>
#include "bubble.h"
Bubble::Bubble(const QPointF &position, qreal radius, const QPointF &velocity)
: position(position), vel(velocity), radius(radius)
{
innerColor = randomColor();
outerColor = randomColor();
cache = 0;
updateBrush();
}
//! [0]
void Bubble::updateCache()
{
if (cache)
delete cache;
cache = new QImage(qRound(radius * 2 + 2), qRound(radius * 2 + 2), QImage::Format_ARGB32);
cache->fill(0x00000000);
QPainter p(cache);
p.setRenderHint(QPainter::HighQualityAntialiasing);
QPen pen(Qt::white);
pen.setWidth(2);
p.setPen(pen);
p.setBrush(brush);
p.drawEllipse(0, 0, int(2*radius), int(2*radius));
}
//! [0]
Bubble::~Bubble()
{
if (cache)
delete cache;
}
void Bubble::updateBrush()
{
QRadialGradient gradient(QPointF(radius, radius), radius,
QPointF(radius*0.5, radius*0.5));
gradient.setColorAt(0, QColor(255, 255, 255, 255));
gradient.setColorAt(0.25, innerColor);
gradient.setColorAt(1, outerColor);
brush = QBrush(gradient);
updateCache();
}
//! [1]
void Bubble::drawBubble(QPainter *painter)
{
painter->save();
painter->translate(position.x() - radius, position.y() - radius);
painter->setOpacity(0.8);
painter->drawImage(0, 0, *cache);
painter->restore();
}
//! [1]
QColor Bubble::randomColor()
{
int red = int(185 + 70.0*qrand()/(RAND_MAX+1.0));
int green = int(185 + 70.0*qrand()/(RAND_MAX+1.0));
int blue = int(205 + 50.0*qrand()/(RAND_MAX+1.0));
int alpha = int(91 + 100.0*qrand()/(RAND_MAX+1.0));
return QColor(red, green, blue, alpha);
}
void Bubble::move(const QRect &bbox)
{
position += vel;
qreal leftOverflow = position.x() - radius - bbox.left();
qreal rightOverflow = position.x() + radius - bbox.right();
qreal topOverflow = position.y() - radius - bbox.top();
qreal bottomOverflow = position.y() + radius - bbox.bottom();
if (leftOverflow < 0.0) {
position.setX(position.x() - 2 * leftOverflow);
vel.setX(-vel.x());
} else if (rightOverflow > 0.0) {
position.setX(position.x() - 2 * rightOverflow);
vel.setX(-vel.x());
}
if (topOverflow < 0.0) {
position.setY(position.y() - 2 * topOverflow);
vel.setY(-vel.y());
} else if (bottomOverflow > 0.0) {
position.setY(position.y() - 2 * bottomOverflow);
vel.setY(-vel.y());
}
}
QRectF Bubble::rect()
{
return QRectF(position.x() - radius, position.y() - radius,
2 * radius, 2 * radius);
}

View File

@ -1,76 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef BUBBLE_H
#define BUBBLE_H
#include <QBrush>
#include <QColor>
#include <QPointF>
#include <QRect>
#include <QRectF>
class QPainter;
class Bubble
{
public:
Bubble(const QPointF &position, qreal radius, const QPointF &velocity);
~Bubble();
void drawBubble(QPainter *painter);
void updateBrush();
void move(const QRect &bbox);
void updateCache();
QRectF rect();
private:
QColor randomColor();
QBrush brush;
QPointF position;
QPointF vel;
qreal radius;
QColor innerColor;
QColor outerColor;
QImage *cache;
};
#endif

View File

@ -1,455 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#include "glwidget.h"
#include <QPainter>
#include <math.h>
#include "bubble.h"
const int bubbleNum = 8;
inline void CrossProduct(qreal &xOut, qreal &yOut, qreal &zOut, qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2)
{
xOut = y1 * z2 - z1 * y2;
yOut = z1 * x2 - x1 * z2;
zOut = x1 * y2 - y1 * x2;
}
inline void Normalize(qreal &x, qreal &y, qreal &z)
{
qreal l = sqrt(x*x + y*y + z*z);
x = x / l;
y = y / l;
z = z / l;
}
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(parent)
{
qtLogo = true;
createdVertices = 0;
createdNormals = 0;
m_vertexNumber = 0;
frames = 0;
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_NoSystemBackground);
setAutoBufferSwap(false);
m_showBubbles = true;
}
GLWidget::~GLWidget()
{
if (createdVertices)
delete[] createdVertices;
if (createdNormals)
delete[] createdNormals;
}
void GLWidget::setScaling(int scale) {
if (scale > 50)
m_fScale = 1 + qreal(scale -50) / 50 * 0.5;
else if (scale < 50)
m_fScale = 1- (qreal(50 - scale) / 50 * 1/2);
else
m_fScale = 1;
}
void GLWidget::setLogo() {
qtLogo = true;
}
void GLWidget::setTexture() {
qtLogo = false;
}
void GLWidget::showBubbles(bool bubbles)
{
m_showBubbles = bubbles;
}
//! [2]
void GLWidget::paintQtLogo()
{
glDisable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0, createdVertices);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT,0,createdNormals);
glDrawArrays(GL_TRIANGLES, 0, m_vertexNumber / 3);
}
//! [2]
void GLWidget::paintTexturedCube()
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_uiTexture);
GLfloat afVertices[] = {
-0.5, 0.5, 0.5, 0.5,-0.5,0.5,-0.5,-0.5,0.5,
0.5, -0.5, 0.5, -0.5,0.5,0.5,0.5,0.5,0.5,
-0.5, -0.5, -0.5, 0.5,-0.5,-0.5,-0.5,0.5,-0.5,
0.5, 0.5, -0.5, -0.5,0.5,-0.5,0.5,-0.5,-0.5,
0.5, -0.5, -0.5, 0.5,-0.5,0.5,0.5,0.5,-0.5,
0.5, 0.5, 0.5, 0.5,0.5,-0.5,0.5,-0.5,0.5,
-0.5, 0.5, -0.5, -0.5,-0.5,0.5,-0.5,-0.5,-0.5,
-0.5, -0.5, 0.5, -0.5,0.5,-0.5,-0.5,0.5,0.5,
0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5,
-0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5,
-0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5,
0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5
};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,afVertices);
GLfloat afTexCoord[] = {
0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
0.0f,1.0f, 1.0f,0.0f, 1.0f,1.0f,
1.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f,
1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f,
0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f
};
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,afTexCoord);
GLfloat afNormals[] = {
0,0,-1, 0,0,-1, 0,0,-1,
0,0,-1, 0,0,-1, 0,0,-1,
0,0,1, 0,0,1, 0,0,1,
0,0,1, 0,0,1, 0,0,1,
-1,0,0, -1,0,0, -1,0,0,
-1,0,0, -1,0,0, -1,0,0,
1,0,0, 1,0,0, 1,0,0,
1,0,0, 1,0,0, 1,0,0,
0,-1,0, 0,-1,0, 0,-1,0,
0,-1,0, 0,-1,0, 0,-1,0,
0,1,0, 0,1,0, 0,1,0,
0,1,0, 0,1,0, 0,1,0
};
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT,0,afNormals);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
void GLWidget::initializeGL ()
{
glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &m_uiTexture);
m_uiTexture = bindTexture(QImage(":/qt.png"));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat aLightPosition[] = {0.0f,0.3f,1.0f,0.0f};
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, aLightPosition);
m_fAngle = 0;
m_fScale = 1;
createGeometry();
createBubbles(bubbleNum - bubbles.count());
}
void GLWidget::paintGL()
{
createBubbles(bubbleNum - bubbles.count());
//! [3]
QPainter painter;
painter.begin(this);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//! [3]
//! [4]
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMatrixMode(GL_TEXTURE);
glPushMatrix();
//Since OpenGL ES does not support glPush/PopAttrib(GL_ALL_ATTRIB_BITS)
//we have to take care of the states ourselves
glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_FLAT);
glFrontFace(GL_CW);
glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(m_fAngle, 0.0f, 1.0f, 0.0f);
glRotatef(m_fAngle, 1.0f, 0.0f, 0.0f);
glRotatef(m_fAngle, 0.0f, 0.0f, 1.0f);
glScalef(m_fScale, m_fScale,m_fScale);
glTranslatef(0.0f,-0.2f,0.0f);
GLfloat matDiff[] = {0.40f, 1.0f, 0.0f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff);
if (qtLogo)
paintQtLogo();
else
paintTexturedCube();
//! [4]
//![5]
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
//![5]
//! [6]
if (m_showBubbles)
foreach (Bubble *bubble, bubbles) {
bubble->drawBubble(&painter);
}
//! [6]
//! [7]
QString framesPerSecond;
framesPerSecond.setNum(frames /(time.elapsed() / 1000.0), 'f', 2);
painter.setPen(Qt::white);
painter.drawText(20, 40, framesPerSecond + " fps");
painter.end();
//! [7]
//! [8]
swapBuffers();
//! [8]
QMutableListIterator<Bubble*> iter(bubbles);
while (iter.hasNext()) {
Bubble *bubble = iter.next();
bubble->move(rect());
}
if (!(frames % 100)) {
time.start();
frames = 0;
}
m_fAngle += 1.0f;
frames ++;
}
void GLWidget::createBubbles(int number)
{
for (int i = 0; i < number; ++i) {
QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))),
height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))));
qreal radius = qMin(width(), height())*(0.0175 + 0.0875*qrand()/(RAND_MAX+1.0));
QPointF velocity(width()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)),
height()*0.0175*(-0.5 + qrand()/(RAND_MAX+1.0)));
bubbles.append(new Bubble(position, radius, velocity));
}
}
void GLWidget::createGeometry()
{
vertices.clear();
normals.clear();
qreal x1 = +0.06f;
qreal y1 = -0.14f;
qreal x2 = +0.14f;
qreal y2 = -0.06f;
qreal x3 = +0.08f;
qreal y3 = +0.00f;
qreal x4 = +0.30f;
qreal y4 = +0.22f;
quad(x1, y1, x2, y2, y2, x2, y1, x1);
quad(x3, y3, x4, y4, y4, x4, y3, x3);
extrude(x1, y1, x2, y2);
extrude(x2, y2, y2, x2);
extrude(y2, x2, y1, x1);
extrude(y1, x1, x1, y1);
extrude(x3, y3, x4, y4);
extrude(x4, y4, y4, x4);
extrude(y4, x4, y3, x3);
const qreal Pi = 3.14159f;
const int NumSectors = 100;
for (int i = 0; i < NumSectors; ++i) {
qreal angle1 = (i * 2 * Pi) / NumSectors;
qreal x5 = 0.30 * sin(angle1);
qreal y5 = 0.30 * cos(angle1);
qreal x6 = 0.20 * sin(angle1);
qreal y6 = 0.20 * cos(angle1);
qreal angle2 = ((i + 1) * 2 * Pi) / NumSectors;
qreal x7 = 0.20 * sin(angle2);
qreal y7 = 0.20 * cos(angle2);
qreal x8 = 0.30 * sin(angle2);
qreal y8 = 0.30 * cos(angle2);
quad(x5, y5, x6, y6, x7, y7, x8, y8);
extrude(x6, y6, x7, y7);
extrude(x8, y8, x5, y5);
}
//! [1]
m_vertexNumber = vertices.size();
createdVertices = new GLfloat[m_vertexNumber];
createdNormals = new GLfloat[m_vertexNumber];
for (int i = 0;i < m_vertexNumber;i++) {
createdVertices[i] = vertices.at(i) * 2;
createdNormals[i] = normals.at(i);
}
vertices.clear();
normals.clear();
}
//! [1]
//! [0]
void GLWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
{
qreal nx, ny, nz;
vertices << x1 << y1 << -0.05f;
vertices << x2 << y2 << -0.05f;
vertices << x4 << y4 << -0.05f;
vertices << x3 << y3 << -0.05f;
vertices << x4 << y4 << -0.05f;
vertices << x2 << y2 << -0.05f;
CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0, x4 - x1, y4 - y1, 0);
Normalize(nx, ny, nz);
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
vertices << x4 << y4 << 0.05f;
vertices << x2 << y2 << 0.05f;
vertices << x1 << y1 << 0.05f;
vertices << x2 << y2 << 0.05f;
vertices << x4 << y4 << 0.05f;
vertices << x3 << y3 << 0.05f;
CrossProduct(nx, ny, nz, x2 - x4, y2 - y4, 0, x1 - x4, y1 - y4, 0);
Normalize(nx, ny, nz);
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
}
//! [0]
void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
{
qreal nx, ny, nz;
vertices << x1 << y1 << +0.05f;
vertices << x2 << y2 << +0.05f;
vertices << x1 << y1 << -0.05f;
vertices << x2 << y2 << -0.05f;
vertices << x1 << y1 << -0.05f;
vertices << x2 << y2 << +0.05f;
CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0.0f, 0.0f, 0.0f, -0.1f);
Normalize(nx, ny, nz);
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
normals << nx << ny << nz;
}

View File

@ -1,85 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget>
#include <QTime>
class Bubble;
class GLWidget : public QGLWidget {
Q_OBJECT
public:
GLWidget(QWidget *parent = 0);
~GLWidget();
public slots:
void setScaling(int scale);
void setLogo();
void setTexture();
void showBubbles(bool);
protected:
void paintGL ();
void initializeGL ();
private:
GLuint m_uiTexture;
qreal m_fAngle;
qreal m_fScale;
bool m_showBubbles;
void paintTexturedCube();
void paintQtLogo();
void createGeometry();
void createBubbles(int number);
void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4);
void extrude(qreal x1, qreal y1, qreal x2, qreal y2);
QList<qreal> vertices;
QList<qreal> normals;
GLfloat *createdVertices;
GLfloat *createdNormals;
int m_vertexNumber;
bool qtLogo;
QList<Bubble*> bubbles;
int frames;
QTime time;
};
#endif

View File

@ -1,11 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Name=Hello GL ES
Exec=/opt/usr/bin/hellogl_es
Icon=hellogl_es
X-Window-Icon=
X-HildonDesk-ShowInToolbar=true
X-Osso-Type=application/x-executable

View File

@ -1,33 +0,0 @@
######################################################################
# Automatically generated by qmake (2.01a) Thu Oct 4 19:01:12 2007
######################################################################
TEMPLATE = app
DEPENDPATH += .
INCLUDEPATH += .
# Input
SOURCES += main.cpp
SOURCES += glwidget.cpp
SOURCES += mainwindow.cpp
SOURCES += bubble.cpp
HEADERS += glwidget.h
HEADERS += mainwindow.h
HEADERS += bubble.h
RESOURCES += texture.qrc
QT += opengl widgets
# install
target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/opengl/hellogl_es
sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS hellogl_es.pro
sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/opengl/hellogl_es
INSTALLS += target sources
symbian: CONFIG += qt_example
maemo5: CONFIG += qt_example
symbian: warning(This example might not fully work on Symbian platform)
maemo5: warning(This example does not work on Maemo platform)
simulator: warning(This example might not fully work on Simulator platform)

View File

@ -1,52 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QApplication>
#include <QMainWindow>
#include "mainwindow.h"
int main( int argc, char ** argv )
{
Q_INIT_RESOURCE(texture);
QApplication a( argc, argv );
MainWindow mw;
mw.showMaximized();
return a.exec();
}

View File

@ -1,107 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mainwindow.h"
#include <QApplication>
#include <QMenuBar>
#include <QGroupBox>
#include <QGridLayout>
#include <QSlider>
#include <QLabel>
#include <QTimer>
#include "glwidget.h"
MainWindow::MainWindow()
{
GLWidget *glwidget = new GLWidget();
QLabel *label = new QLabel(this);
QTimer *timer = new QTimer(this);
QSlider *slider = new QSlider(this);
slider->setOrientation(Qt::Horizontal);
slider->setRange(0, 100);
slider->setSliderPosition(50);
timer->setInterval(10);
label->setText("A QGlWidget with OpenGl ES");
label->setAlignment(Qt::AlignHCenter);
QGroupBox * groupBox = new QGroupBox(this);
setCentralWidget(groupBox);
groupBox->setTitle("OpenGL ES Example");
QGridLayout *layout = new QGridLayout(groupBox);
layout->addWidget(glwidget,1,0,8,1);
layout->addWidget(label,9,0,1,1);
layout->addWidget(slider, 11,0,1,1);
groupBox->setLayout(layout);
QMenu *fileMenu = new QMenu("File");
QMenu *helpMenu = new QMenu("Help");
QMenu *showMenu = new QMenu("Show");
menuBar()->addMenu(fileMenu);
menuBar()->addMenu(showMenu);
menuBar()->addMenu(helpMenu);
QAction *exit = new QAction("Exit", fileMenu);
QAction *aboutQt = new QAction("AboutQt", helpMenu);
QAction *showLogo = new QAction("Show 3D Logo", showMenu);
QAction *showTexture = new QAction("Show 2D Texture", showMenu);
QAction *showBubbles = new QAction("Show bubbles", showMenu);
showBubbles->setCheckable(true);
showBubbles->setChecked(true);
fileMenu->addAction(exit);
helpMenu->addAction(aboutQt);
showMenu->addAction(showLogo);
showMenu->addAction(showTexture);
showMenu->addAction(showBubbles);
QObject::connect(timer, SIGNAL(timeout()), glwidget, SLOT(updateGL()));
QObject::connect(exit, SIGNAL(triggered(bool)), this, SLOT(close()));
QObject::connect(aboutQt, SIGNAL(triggered(bool)), qApp, SLOT(aboutQt()));
QObject::connect(showLogo, SIGNAL(triggered(bool)), glwidget, SLOT(setLogo()));
QObject::connect(showTexture, SIGNAL(triggered(bool)), glwidget, SLOT(setTexture()));
QObject::connect(showBubbles, SIGNAL(triggered(bool)), glwidget, SLOT(showBubbles(bool)));
QObject::connect(slider, SIGNAL(valueChanged(int)), glwidget, SLOT(setScaling(int)));
timer->start();
}

View File

@ -1,59 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class QSlider;
class GLWidget;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
private:
};
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>qt.png</file>
</qresource>
</RCC>

View File

@ -2047,20 +2047,11 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
bool QGL2PaintEngineEx::end()
{
Q_D(QGL2PaintEngineEx);
QGLContext *ctx = d->ctx;
glUseProgram(0);
d->transferMode(BrushDrawingMode);
d->device->endPaint();
#if defined(Q_WS_X11)
// On some (probably all) drivers, deleting an X pixmap which has been bound to a texture
// before calling glFinish/swapBuffers renders garbage. Presumably this is because X deletes
// the pixmap behind the driver's back before it's had a chance to use it. To fix this, we
// reference all QPixmaps which have been bound to stop them being deleted and only deref
// them here, after swapBuffers, where they can be safely deleted.
ctx->d_func()->boundPixmaps.clear();
#endif
d->ctx->d_ptr->active_engine = 0;
d->resetGLState();

View File

@ -59,7 +59,6 @@
#include <private/qglengineshadermanager_p.h>
#include <private/qgl2pexvertexarray_p.h>
#include <private/qglpaintdevice_p.h>
#include <private/qglpixmapfilter_p.h>
#include <private/qfontengine_p.h>
#include <private/qdatabuffer_p.h>
#include <private/qtriangulatingstroker_p.h>
@ -153,8 +152,6 @@ public:
void invalidateState();
QPixmapFilter *pixmapFilter(int type, const QPixmapFilter *prototype);
void setRenderTextActive(bool);
bool isNativePaintingActive() const;
@ -302,11 +299,6 @@ public:
QTriangulatingStroker stroker;
QDashedStrokeProcessor dasher;
QScopedPointer<QPixmapFilter> convolutionFilter;
QScopedPointer<QPixmapFilter> colorizeFilter;
QScopedPointer<QPixmapFilter> blurFilter;
QScopedPointer<QPixmapFilter> dropShadowFilter;
QSet<QVectorPath::CacheEntry *> pathCaches;
QVector<GLuint> unusedVBOSToClean;
QVector<GLuint> unusedIBOSToClean;

View File

@ -43,10 +43,6 @@
#include "qpaintengineex_opengl2_p.h"
#include "private/qglengineshadersource_p.h"
#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL)
#include "private/qeglcontext_p.h"
#endif
QT_BEGIN_NAMESPACE
#ifdef Q_WS_WIN

View File

@ -47,95 +47,35 @@ SOURCES += qgl.cpp \
qglpaintdevice.cpp \
qglbuffer.cpp \
HEADERS += qglshaderprogram.h \
qgraphicsshadereffect_p.h \
gl2paintengineex/qglgradientcache_p.h \
gl2paintengineex/qglengineshadermanager_p.h \
gl2paintengineex/qgl2pexvertexarray_p.h \
gl2paintengineex/qpaintengineex_opengl2_p.h \
gl2paintengineex/qglengineshadersource_p.h \
gl2paintengineex/qglcustomshaderstage_p.h \
gl2paintengineex/qtriangulatingstroker_p.h \
gl2paintengineex/qtriangulator_p.h \
gl2paintengineex/qrbtree_p.h \
gl2paintengineex/qtextureglyphcache_gl_p.h \
gl2paintengineex/qglshadercache_p.h \
gl2paintengineex/qglshadercache_meego_p.h
!contains(QT_CONFIG, opengles2) {
HEADERS += qpaintengine_opengl_p.h
SOURCES += qpaintengine_opengl.cpp
}
SOURCES += qglshaderprogram.cpp \
qgraphicsshadereffect.cpp \
gl2paintengineex/qglgradientcache.cpp \
gl2paintengineex/qglengineshadermanager.cpp \
gl2paintengineex/qgl2pexvertexarray.cpp \
gl2paintengineex/qpaintengineex_opengl2.cpp \
gl2paintengineex/qglcustomshaderstage.cpp \
gl2paintengineex/qtriangulatingstroker.cpp \
gl2paintengineex/qtriangulator.cpp \
gl2paintengineex/qtextureglyphcache_gl.cpp
!contains(QT_CONFIG, opengles1) {
HEADERS += qglshaderprogram.h \
qglpixmapfilter_p.h \
qgraphicsshadereffect_p.h \
gl2paintengineex/qglgradientcache_p.h \
gl2paintengineex/qglengineshadermanager_p.h \
gl2paintengineex/qgl2pexvertexarray_p.h \
gl2paintengineex/qpaintengineex_opengl2_p.h \
gl2paintengineex/qglengineshadersource_p.h \
gl2paintengineex/qglcustomshaderstage_p.h \
gl2paintengineex/qtriangulatingstroker_p.h \
gl2paintengineex/qtriangulator_p.h \
gl2paintengineex/qrbtree_p.h \
gl2paintengineex/qtextureglyphcache_gl_p.h \
gl2paintengineex/qglshadercache_p.h \
gl2paintengineex/qglshadercache_meego_p.h
SOURCES += qgl_qpa.cpp \
qglpixelbuffer_stub.cpp
SOURCES += qglshaderprogram.cpp \
qglpixmapfilter.cpp \
qgraphicsshadereffect.cpp \
gl2paintengineex/qglgradientcache.cpp \
gl2paintengineex/qglengineshadermanager.cpp \
gl2paintengineex/qgl2pexvertexarray.cpp \
gl2paintengineex/qpaintengineex_opengl2.cpp \
gl2paintengineex/qglcustomshaderstage.cpp \
gl2paintengineex/qtriangulatingstroker.cpp \
gl2paintengineex/qtriangulator.cpp \
gl2paintengineex/qtextureglyphcache_gl.cpp
}
qpa {
SOURCES += qgl_qpa.cpp \
qglpixelbuffer_stub.cpp
}
x11 {
contains(QT_CONFIG, egl) {
SOURCES += qgl_x11egl.cpp \
qglpixelbuffer_egl.cpp \
qgl_egl.cpp
HEADERS += qgl_egl_p.h
} else {
SOURCES += qgl_x11.cpp \
qglpixelbuffer_x11.cpp
}
contains(QT_CONFIG, fontconfig) {
contains(QT_CONFIG, system-freetype) {
# pull in the proper freetype2 include directory
include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
LIBS_PRIVATE += -lfreetype
} else {
### Note: how does this compile with a non-system freetype?
# This probably does not compile
}
} else {
DEFINES *= QT_NO_FREETYPE
}
LIBS_PRIVATE += $$QMAKE_LIBS_DYNLOAD
}
mac:!qpa {
OBJECTIVE_SOURCES += qgl_mac.mm \
qglpixelbuffer_mac.mm
LIBS_PRIVATE += -framework AppKit -framework Carbon
}
win32:!wince*: {
DEFINES += QT_NO_EGL
!qpa {
SOURCES += qgl_win.cpp \
qglpixelbuffer_win.cpp
}
}
wince*: {
SOURCES += qgl_wince.cpp \
qglpixelbuffer_egl.cpp \
qgl_egl.cpp
HEADERS += qgl_egl_p.h
}
DEFINES += QT_NO_EGL
INCLUDEPATH += ../3rdparty/harfbuzz/src

View File

@ -45,21 +45,6 @@
#include <qdebug.h>
#include <qglfunctions.h>
#if defined(Q_WS_X11)
#include "private/qt_x11_p.h"
#include "private/qpixmap_x11_p.h"
#define INT32 dummy_INT32
#define INT8 dummy_INT8
#ifdef QT_NO_EGL
# include <GL/glx.h>
#endif
#undef INT32
#undef INT8
#include "qx11info_x11.h"
#elif defined(Q_WS_MAC)
# include <private/qt_mac_p.h>
#endif
#include <qdatetime.h>
#include <stdlib.h> // malloc
@ -68,17 +53,9 @@
#include "qimage.h"
#include "qgl_p.h"
#if !defined(QT_OPENGL_ES_1)
#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
#endif
#ifndef QT_OPENGL_ES_2
#include <private/qpaintengine_opengl_p.h>
#endif
#ifdef Q_WS_QPA
#include <QtGui/QPlatformGLContext>
#endif
#include <qglpixelbuffer.h>
#include <qglframebufferobject.h>
@ -92,21 +69,11 @@
#include "qlibrary.h"
#include <qmutex.h>
#if defined(QT_OPENGL_ES) && !defined(QT_NO_EGL)
#include <EGL/egl.h>
#endif
// #define QT_GL_CONTEXT_RESOURCE_DEBUG
QT_BEGIN_NAMESPACE
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
#endif
#ifdef Q_WS_X11
extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
#endif
struct QGLThreadContext {
~QGLThreadContext() {
@ -116,10 +83,6 @@ struct QGLThreadContext {
QGLContext *context;
};
#ifndef Q_WS_QPA
static QThreadStorage<QGLThreadContext *> qgl_context_storage;
#endif
Q_GLOBAL_STATIC(QGLFormat, qgl_default_format)
class QGLDefaultOverlayFormat: public QGLFormat
@ -146,71 +109,6 @@ QGLSignalProxy *QGLSignalProxy::instance()
}
class QGLEngineSelector
{
public:
QGLEngineSelector() : engineType(QPaintEngine::MaxUser)
{
}
void setPreferredPaintEngine(QPaintEngine::Type type) {
if (type == QPaintEngine::OpenGL || type == QPaintEngine::OpenGL2)
engineType = type;
}
QPaintEngine::Type preferredPaintEngine() {
#ifdef Q_WS_MAC
// The ATI X1600 driver for Mac OS X does not support return
// values from functions in GLSL. Since working around this in
// the GL2 engine would require a big, ugly rewrite, we're
// falling back to the GL 1 engine..
static bool mac_x1600_check_done = false;
if (!mac_x1600_check_done) {
QGLTemporaryContext *tmp = 0;
if (!QGLContext::currentContext())
tmp = new QGLTemporaryContext();
if (strstr((char *) glGetString(GL_RENDERER), "X1600"))
engineType = QPaintEngine::OpenGL;
if (tmp)
delete tmp;
mac_x1600_check_done = true;
}
#endif
if (engineType == QPaintEngine::MaxUser) {
// No user-set engine - use the defaults
#if defined(QT_OPENGL_ES_2)
engineType = QPaintEngine::OpenGL2;
#else
// We can't do this in the constructor for this object because it
// needs to be called *before* the QApplication constructor.
// Also check for the FragmentShader extension in conjunction with
// the 2.0 version flag, to cover the case where we export the display
// from an old GL 1.1 server to a GL 2.x client. In that case we can't
// use GL 2.0.
if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
&& (QGLExtensions::glExtensions() & QGLExtensions::FragmentShader)
&& qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
engineType = QPaintEngine::OpenGL2;
else
engineType = QPaintEngine::OpenGL;
#endif
}
return engineType;
}
private:
QPaintEngine::Type engineType;
};
Q_GLOBAL_STATIC(QGLEngineSelector, qgl_engine_selector)
bool qt_gl_preferGL2Engine()
{
return qgl_engine_selector()->preferredPaintEngine() == QPaintEngine::OpenGL2;
}
/*!
\namespace QGL
\inmodule QtOpenGL
@ -257,32 +155,6 @@ bool qt_gl_preferGL2Engine()
\sa {Sample Buffers Example}
*/
/*!
\fn void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
\since 4.6
Sets the preferred OpenGL paint engine that is used to draw onto
QGLWidget, QGLPixelBuffer and QGLFramebufferObject targets with QPainter
in Qt.
The \a engineType parameter specifies which of the GL engines to
use. Only \c QPaintEngine::OpenGL and \c QPaintEngine::OpenGL2 are
valid parameters to this function. All other values are ignored.
By default, the \c QPaintEngine::OpenGL2 engine is used if GL/GLES
version 2.0 is available, otherwise \c QPaintEngine::OpenGL is
used.
\warning This function must be called before the QApplication
constructor is called.
*/
void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
{
qgl_engine_selector()->setPreferredPaintEngine(engineType);
}
/*****************************************************************************
QGLFormat implementation
*****************************************************************************/
@ -1680,35 +1552,8 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
glFormat = reqFormat = format;
valid = false;
q->setDevice(dev);
#if defined(Q_WS_X11)
pbuf = 0;
gpm = 0;
vi = 0;
screen = QX11Info::appScreen();
#endif
#if defined(Q_WS_WIN)
dc = 0;
win = 0;
threadId = 0;
pixelFormatId = 0;
cmap = 0;
hbitmap = 0;
hbitmap_hdc = 0;
#endif
#if defined(Q_WS_MAC)
# ifndef QT_MAC_USE_COCOA
update = false;
# endif
vi = 0;
#endif
#if defined(Q_WS_QPA)
guiGlContext = 0;
#endif
#if !defined(QT_NO_EGL)
ownsEglContext = false;
eglContext = 0;
eglSurface = EGL_NO_SURFACE;
#endif
fbo = 0;
crWin = false;
initDone = false;
@ -1802,7 +1647,7 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp
QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
int w = size.width();
int h = size.height();
#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1)
#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
@ -1912,13 +1757,6 @@ void QGLTextureCache::cleanupBeforePixmapDestruction(QPlatformPixmap* pmd)
{
// Remove any bound textures first:
cleanupTexturesForPixampData(pmd);
#if defined(Q_WS_X11)
if (pmd->classId() == QPlatformPixmap::X11Class) {
Q_ASSERT(pmd->ref == 0); // Make sure reference counting isn't broken
QGLContextPrivate::destroyGlSurfaceForPixmap(pmd);
}
#endif
}
QGLTextureCache *QGLTextureCache::instance()
@ -2139,13 +1977,11 @@ void QGLContextPrivate::syncGlState()
}
#undef ctx
#ifdef QT_NO_EGL
void QGLContextPrivate::swapRegion(const QRegion &)
{
Q_Q(QGLContext);
q->swapBuffers();
}
#endif
/*!
\overload
@ -2290,12 +2126,10 @@ static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum textu
}
}
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
QGLExtensionFuncs& QGLContextPrivate::extensionFuncs(const QGLContext *)
{
return qt_extensionFuncs;
}
#endif
QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_premul,
GLenum texture_format)
@ -2594,39 +2428,6 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
}
}
#if defined(Q_WS_X11)
// Try to use texture_from_pixmap
const QX11Info *xinfo = qt_x11Info(paintDevice);
if (pd->classId() == QPlatformPixmap::X11Class && pd->pixelType() == QPlatformPixmap::PixmapType
&& xinfo && xinfo->screen() == pixmap.x11Info().screen()
&& target == GL_TEXTURE_2D
&& QApplication::instance()->thread() == QThread::currentThread())
{
if (!workaround_brokenTextureFromPixmap_init) {
workaround_brokenTextureFromPixmap_init = true;
const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
const int pos = versionString.indexOf("NVIDIA ");
if (pos >= 0) {
const QByteArray nvidiaVersionString = versionString.mid(pos + strlen("NVIDIA "));
if (nvidiaVersionString.startsWith("195") || nvidiaVersionString.startsWith("256"))
workaround_brokenTextureFromPixmap = true;
}
}
if (!workaround_brokenTextureFromPixmap) {
texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options);
if (texture) {
texture->options |= QGLContext::MemoryManagedBindOption;
texture->boundPixmap = pd;
boundPixmaps.insert(pd, QPixmap(pixmap));
}
}
}
#endif
if (!texture) {
QImage image = pixmap.toImage();
// If the system depth is 16 and the pixmap doesn't have an alpha channel
@ -2745,31 +2546,6 @@ GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format,
return texture->id;
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
{
if (image.isNull())
return 0;
Q_D(QGLContext);
QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), DefaultBindOption);
return texture->id;
}
/*! \internal */
GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
BindOptions options)
{
if (image.isNull())
return 0;
Q_D(QGLContext);
QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), options);
return texture->id;
}
#endif
/*! \overload
Generates and binds a 2D GL texture based on \a pixmap.
@ -2801,30 +2577,6 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint forma
return texture->id;
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format)
{
if (pixmap.isNull())
return 0;
Q_D(QGLContext);
QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), DefaultBindOption);
return texture->id;
}
/*! \internal */
GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
BindOptions options)
{
if (pixmap.isNull())
return 0;
Q_D(QGLContext);
QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), options);
return texture->id;
}
#endif
/*!
Removes the texture identified by \a id from the texture cache,
and calls glDeleteTextures() to delete the texture from the
@ -2839,14 +2591,6 @@ void QGLContext::deleteTexture(GLuint id)
glDeleteTextures(1, &id);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLContext::deleteTexture(QMacCompatGLuint id)
{
return deleteTexture(GLuint(id));
}
#endif
void qt_add_rect_to_array(const QRectF &r, GLfloat *array)
{
qreal left = r.left();
@ -2986,14 +2730,6 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
#endif
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLContext::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
drawTexture(target, GLuint(textureId), GLenum(textureTarget));
}
#endif
/*!
\since 4.4
@ -3057,15 +2793,6 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
#endif
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLContext::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
drawTexture(point, GLuint(textureId), GLenum(textureTarget));
}
#endif
/*!
This function sets the limit for the texture cache to \a size,
expressed in kilobytes.
@ -3295,11 +3022,7 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex
bool QGLContext::create(const QGLContext* shareContext)
{
Q_D(QGLContext);
#ifdef Q_WS_QPA
if (!d->paintDevice && !d->guiGlContext)
#else
if (!d->paintDevice)
#endif
return false;
reset();
@ -3308,10 +3031,6 @@ bool QGLContext::create(const QGLContext* shareContext)
QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice));
wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer();
}
#ifndef Q_WS_QPA //We do this in choose context->setupSharing()
if (d->sharing) // ok, we managed to share
QGLContextGroup::addShare(this, shareContext);
#endif
return d->valid;
}
@ -3385,37 +3104,15 @@ void QGLContext::setInitialized(bool on)
const QGLContext* QGLContext::currentContext()
{
#ifdef Q_WS_QPA
if (const QGuiGLContext *threadContext = QGuiGLContext::currentContext()) {
return QGLContext::fromGuiGLContext(const_cast<QGuiGLContext *>(threadContext));
}
return 0;
#else
QGLThreadContext *threadContext = qgl_context_storage.localData();
if (threadContext)
return threadContext->context;
return 0;
#endif //Q_WS_QPA
}
void QGLContextPrivate::setCurrentContext(QGLContext *context)
{
#ifdef Q_WS_QPA
Q_UNUSED(context);
#else
QGLThreadContext *threadContext = qgl_context_storage.localData();
if (!threadContext) {
if (!QThread::currentThread()) {
// We don't have a current QThread, so just set the static.
QGLContext::currentCtx = context;
return;
}
threadContext = new QGLThreadContext;
qgl_context_storage.setLocalData(threadContext);
}
threadContext->context = context;
QGLContext::currentCtx = context; // XXX: backwards-compat, not thread-safe
#endif
}
/*!
@ -3727,11 +3424,6 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
on a QGLWidget and the widget's rendering context is current in
another thread, it will fail.
Note that under X11 it is necessary to set the
Qt::AA_X11InitThreads application attribute to make the X11
library and GLX calls thread safe, otherwise the above scenarios
will fail.
In addition to this, rendering using raw GL calls in a separate
thread is supported.
@ -3872,30 +3564,9 @@ QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, const QGLWidget *shar
QGLWidget::~QGLWidget()
{
Q_D(QGLWidget);
#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
bool doRelease = (glcx && glcx->windowCreated());
#endif
delete d->glcx;
d->glcx = 0;
#if defined(Q_WS_WIN)
delete d->olcx;
d->olcx = 0;
#endif
#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
if (doRelease)
glXReleaseBuffersMESA(x11Display(), winId());
#endif
d->cleanupColormaps();
#ifdef Q_WS_MAC
QWidget *current = parentWidget();
while (current) {
qt_widget_private(current)->glWidgets.removeAll(QWidgetPrivate::GlWidgetInfo(this));
if (current->isWindow())
break;
current = current->parentWidget();
};
#endif
}
/*!
@ -4241,125 +3912,6 @@ void QGLWidget::resizeOverlayGL(int, int)
{
}
/*! \fn bool QGLWidget::event(QEvent *e)
\reimp
*/
#if !defined(Q_OS_WINCE) && !defined(Q_WS_QWS) && !defined(Q_WS_QPA)
bool QGLWidget::event(QEvent *e)
{
Q_D(QGLWidget);
if (e->type() == QEvent::Paint) {
QPoint offset;
QPaintDevice *redirectedDevice = d->redirected(&offset);
if (redirectedDevice && redirectedDevice->devType() == QInternal::Pixmap) {
d->restoreRedirected();
QPixmap pixmap = renderPixmap();
d->setRedirected(redirectedDevice, offset);
QPainter p(redirectedDevice);
p.drawPixmap(-offset, pixmap);
return true;
}
}
#if defined(Q_WS_X11)
if (e->type() == QEvent::ParentChange) {
// if we've reparented a window that has the current context
// bound, we need to rebind that context to the new window id
if (d->glcx == QGLContext::currentContext())
makeCurrent();
if (d->glcx->d_func()->screen != d->xinfo.screen() || testAttribute(Qt::WA_TranslucentBackground)) {
setContext(new QGLContext(d->glcx->requestedFormat(), this));
// ### recreating the overlay isn't supported atm
}
}
#ifndef QT_NO_EGL
// A re-parent is likely to destroy the X11 window and re-create it. It is important
// that we free the EGL surface _before_ the winID changes - otherwise we can leak.
if (e->type() == QEvent::ParentAboutToChange)
d->glcx->d_func()->destroyEglSurfaceForDevice();
if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
// The window may have been re-created during re-parent or state change - if so, the EGL
// surface will need to be re-created.
d->recreateEglSurface();
}
#endif
#elif defined(Q_WS_WIN)
if (e->type() == QEvent::ParentChange) {
QGLContext *newContext = new QGLContext(d->glcx->requestedFormat(), this);
setContext(newContext, d->glcx);
// the overlay needs to be recreated as well
delete d->olcx;
if (isValid() && context()->format().hasOverlay()) {
d->olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), this);
if (!d->olcx->create(isSharing() ? d->glcx : 0)) {
delete d->olcx;
d->olcx = 0;
d->glcx->d_func()->glFormat.setOverlay(false);
}
} else {
d->olcx = 0;
}
} else if (e->type() == QEvent::Show) {
if (!format().rgba())
d->updateColormap();
}
#elif defined(Q_WS_MAC)
if (e->type() == QEvent::MacGLWindowChange
#if 0 //(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
&& ((QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && isWindow())
|| QSysInfo::MacintoshVersion <= QSysInfo::MV_10_4)
#endif
) {
if (d->needWindowChange) {
d->needWindowChange = false;
d->glcx->updatePaintDevice();
update();
}
return true;
# if defined(QT_MAC_USE_COCOA)
} else if (e->type() == QEvent::MacGLClearDrawable) {
d->glcx->d_ptr->clearDrawable();
# endif
}
#elif defined(Q_OS_SYMBIAN)
// prevents errors on some systems, where we get a flush to a
// hidden widget
if (e->type() == QEvent::Hide) {
makeCurrent();
glFinish();
doneCurrent();
} else if (e->type() == QEvent::ParentChange) {
// if we've reparented a window that has the current context
// bound, we need to rebind that context to the new window id
if (d->glcx == QGLContext::currentContext())
makeCurrent();
if (testAttribute(Qt::WA_TranslucentBackground))
setContext(new QGLContext(d->glcx->requestedFormat(), this));
}
// A re-parent is likely to destroy the Symbian window and re-create it. It is important
// that we free the EGL surface _before_ the winID changes - otherwise we can leak.
if (e->type() == QEvent::ParentAboutToChange)
d->glcx->d_func()->destroyEglSurfaceForDevice();
if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
// The window may have been re-created during re-parent or state change - if so, the EGL
// surface will need to be re-created.
d->recreateEglSurface();
}
#endif
return QWidget::event(e);
}
#endif
/*!
\fn void QGLWidget::paintEvent(QPaintEvent *event)
@ -4433,28 +3985,7 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
if ((w > 0) && (h > 0))
sz = QSize(w, h);
#if defined(Q_WS_X11)
extern int qt_x11_preferred_pixmap_depth;
int old_depth = qt_x11_preferred_pixmap_depth;
qt_x11_preferred_pixmap_depth = x11Info().depth();
QPlatformPixmap *data = new QX11PlatformPixmap(QPlatformPixmap::PixmapType);
data->resize(sz.width(), sz.height());
QPixmap pm(data);
qt_x11_preferred_pixmap_depth = old_depth;
QX11Info xinfo = x11Info();
// make sure we use a pixmap with the same depth/visual as the widget
if (xinfo.visual() != QX11Info::appVisual()) {
QX11InfoData* xd = pm.x11Info().getX11Data(true);
xd->depth = xinfo.depth();
xd->visual = static_cast<Visual *>(xinfo.visual());
const_cast<QX11Info &>(pm.x11Info()).setX11Data(xd);
}
#else
QPixmap pm(sz);
#endif
d->glcx->doneCurrent();
@ -4466,9 +3997,6 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
QGLFormat fmt = d->glcx->requestedFormat();
fmt.setDirectRendering(false); // Direct is unlikely to work
fmt.setDoubleBuffer(false); // We don't need dbl buf
#ifdef Q_WS_MAC // crash prevention on the Mac - it's unlikely to work anyway
fmt.setSampleBuffers(false);
#endif
QGLContext* ocx = d->glcx;
ocx->doneCurrent();
@ -4486,13 +4014,6 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
ocx->makeCurrent();
if (success) {
#if defined(Q_WS_X11)
if (xinfo.visual() != QX11Info::appVisual()) {
QImage image = pm.toImage();
QPixmap p = QPixmap::fromImage(image);
return p;
}
#endif
return pm;
}
return QPixmap();
@ -4512,21 +4033,8 @@ QImage QGLWidget::grabFrameBuffer(bool withAlpha)
QImage res;
int w = width();
int h = height();
if (format().rgba()) {
if (format().rgba())
res = qt_gl_read_framebuffer(QSize(w, h), format().alpha(), withAlpha);
} else {
#if defined (Q_WS_WIN) && !defined(QT_OPENGL_ES)
res = QImage(w, h, QImage::Format_Indexed8);
glReadPixels(0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, res.bits());
const QVector<QColor> pal = QColormap::instance().colormap();
if (pal.size()) {
res.setColorCount(pal.size());
for (int i = 0; i < pal.size(); i++)
res.setColor(i, pal.at(i).rgb());
}
res = res.mirrored();
#endif
}
return res;
}
@ -4561,11 +4069,6 @@ void QGLWidget::glDraw()
Q_D(QGLWidget);
if (!isValid())
return;
#ifdef Q_OS_SYMBIAN
// Crashes on Symbian if trying to render to invisible surfaces
if (!isVisible() && d->glcx->device()->devType() == QInternal::Widget)
return;
#endif
makeCurrent();
#ifndef QT_OPENGL_ES
if (d->glcx->deviceIsPixmap())
@ -4884,10 +4387,8 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
int height = d->glcx->device()->height();
bool auto_swap = autoBufferSwap();
QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
QPaintEngine *engine = paintEngine();
if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
if (engine && engine->isActive()) {
qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
" active on the same device is not allowed.");
return;
@ -4939,7 +4440,6 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
@ -4987,10 +4487,9 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
&win_x, &win_y, &win_z);
win_y = height - win_y; // y is inverted
QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
QPaintEngine *engine = paintEngine();
if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
if (engine && engine->isActive()) {
qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
" active on the same device is not allowed.");
return;
@ -5043,7 +4542,6 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
@ -5116,28 +4614,6 @@ GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format,
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
{
if (image.isNull())
return 0;
Q_D(QGLWidget);
return d->glcx->bindTexture(image, GLenum(target), GLint(format), QGLContext::DefaultBindOption);
}
GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
QGLContext::BindOptions options)
{
if (image.isNull())
return 0;
Q_D(QGLWidget);
return d->glcx->bindTexture(image, GLenum(target), GLint(format), options);
}
#endif
/*!
Calls QGLContext:::bindTexture(\a pixmap, \a target, \a format) on the currently
set context.
@ -5170,23 +4646,6 @@ GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format
return d->glcx->bindTexture(pixmap, target, format, options);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
GLuint QGLWidget::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format)
{
Q_D(QGLWidget);
return d->glcx->bindTexture(pixmap, target, format, QGLContext::DefaultBindOption);
}
GLuint QGLWidget::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
QGLContext::BindOptions options)
{
Q_D(QGLWidget);
return d->glcx->bindTexture(pixmap, target, format, options);
}
#endif
/*! \overload
Calls QGLContext::bindTexture(\a fileName) on the currently set context.
@ -5211,15 +4670,6 @@ void QGLWidget::deleteTexture(GLuint id)
d->glcx->deleteTexture(id);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLWidget::deleteTexture(QMacCompatGLuint id)
{
Q_D(QGLWidget);
d->glcx->deleteTexture(GLuint(id));
}
#endif
/*!
\since 4.4
@ -5233,15 +4683,6 @@ void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textu
d->glcx->drawTexture(target, textureId, textureTarget);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLWidget::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
Q_D(QGLWidget);
d->glcx->drawTexture(target, GLint(textureId), GLenum(textureTarget));
}
#endif
/*!
\since 4.4
@ -5255,42 +4696,17 @@ void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textu
d->glcx->drawTexture(point, textureId, textureTarget);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
Q_D(QGLWidget);
d->glcx->drawTexture(point, GLuint(textureId), GLenum(textureTarget));
}
#endif
#ifndef QT_OPENGL_ES_1
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_gl_2_engine)
#endif
#ifndef QT_OPENGL_ES_2
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_gl_engine)
#endif
Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine()
{
#if defined(QT_OPENGL_ES_1)
return qt_gl_engine()->engine();
#elif defined(QT_OPENGL_ES_2)
return qt_gl_2_engine()->engine();
#else
if (qt_gl_preferGL2Engine())
return qt_gl_2_engine()->engine();
else
return qt_gl_engine()->engine();
#endif
}
/*!
\internal
Returns the GL widget's paint engine. This is normally a
QOpenGLPaintEngine.
Returns the GL widget's paint engine.
*/
QPaintEngine *QGLWidget::paintEngine() const
{
@ -5458,10 +4874,6 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
glExtensions |= GenerateMipmap;
glExtensions |= FragmentShader;
#endif
#if defined(QT_OPENGL_ES_1)
if (extensions.match("GL_OES_framebuffer_object"))
glExtensions |= FramebufferObject;
#endif
#if defined(QT_OPENGL_ES)
if (extensions.match("GL_OES_packed_depth_stencil"))
glExtensions |= PackedDepthStencil;
@ -5554,7 +4966,6 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi
glcx = new QGLContext(QGLFormat::defaultFormat(), q);
}
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA)
Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
@ -5565,21 +4976,14 @@ Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
Q_OPENGL_EXPORT const QString qt_gl_library_name()
{
if (qt_gl_lib_name()->isNull()) {
#ifdef Q_WS_MAC
return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib");
#else
# if defined(QT_OPENGL_ES_1)
return QLatin1String("GLES_CM");
# elif defined(QT_OPENGL_ES_2)
# if defined(QT_OPENGL_ES_2)
return QLatin1String("GLESv2");
# else
return QLatin1String("GL");
# endif
#endif // defined Q_WS_MAC
}
return *qt_gl_lib_name();
}
#endif
void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) {
Q_ASSERT(context && share);

View File

@ -58,18 +58,6 @@ QT_BEGIN_HEADER
#if defined(Q_OS_MAC)
# include <OpenGL/gl.h>
#elif defined(QT_OPENGL_ES_1)
# if defined(Q_OS_MAC)
# include <OpenGLES/ES1/gl.h>
# else
# include <GLES/gl.h>
# endif
# ifndef GL_DOUBLE
# define GL_DOUBLE GL_FLOAT
# endif
# ifndef GLdouble
typedef GLfloat GLdouble;
# endif
#elif defined(QT_OPENGL_ES_2)
# if defined(Q_OS_MAC)
# include <OpenGLES/ES2/gl.h>
@ -94,31 +82,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(OpenGL)
#if defined(Q_WS_MAC) && defined (QT_BUILD_OPENGL_LIB) && !defined(QT_MAC_USE_COCOA) && !defined(QDOC)
#define Q_MAC_COMPAT_GL_FUNCTIONS
template <typename T>
struct QMacGLCompatTypes
{
typedef long CompatGLint;
typedef unsigned long CompatGLuint;
typedef unsigned long CompatGLenum;
};
template <>
struct QMacGLCompatTypes<long>
{
typedef int CompatGLint;
typedef unsigned int CompatGLuint;
typedef unsigned int CompatGLenum;
};
typedef QMacGLCompatTypes<GLint>::CompatGLint QMacCompatGLint;
typedef QMacGLCompatTypes<GLint>::CompatGLuint QMacCompatGLuint;
typedef QMacGLCompatTypes<GLint>::CompatGLenum QMacCompatGLenum;
#endif
#ifdef QT3_SUPPORT
#define QGL_VERSION 460
#define QGL_VERSION_STR "4.6"
@ -132,9 +95,6 @@ class QGLCmap;
#endif
class QPixmap;
#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
class QGLOverlayWidget;
#endif
class QGLWidgetPrivate;
class QGLContextPrivate;
@ -371,22 +331,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
GLuint bindTexture(const QImage &image, QMacCompatGLenum = GL_TEXTURE_2D,
QMacCompatGLint format = GL_RGBA);
GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum = GL_TEXTURE_2D,
QMacCompatGLint format = GL_RGBA);
GLuint bindTexture(const QImage &image, QMacCompatGLenum, QMacCompatGLint format,
BindOptions);
GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum, QMacCompatGLint format,
BindOptions);
void deleteTexture(QMacCompatGLuint tx_id);
void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
#endif
static void setTextureCacheLimit(int size);
static int textureCacheLimit();
@ -396,25 +340,12 @@ public:
static const QGLContext* currentContext();
#ifdef Q_WS_QPA
static QGLContext *fromGuiGLContext(QGuiGLContext *platformContext);
QGuiGLContext *contextHandle() const;
#endif
protected:
virtual bool chooseContext(const QGLContext* shareContext = 0);
#if defined(Q_WS_WIN)
virtual int choosePixelFormat(void* pfd, HDC pdc);
#endif
#if defined(Q_WS_X11) && defined(QT_NO_EGL)
virtual void* tryVisual(const QGLFormat& f, int bufDepth = 1);
virtual void* chooseVisual();
#endif
#if defined(Q_WS_MAC)
virtual void* chooseMacVisual(GDHandle);
#endif
bool deviceIsPixmap() const;
bool windowCreated() const;
void setWindowCreated(bool on);
@ -430,9 +361,7 @@ protected:
static QGLContext* currentCtx;
private:
#ifdef Q_WS_QPA
QGLContext(QGuiGLContext *windowContext);
#endif
QScopedPointer<QGLContextPrivate> d_ptr;
@ -441,12 +370,9 @@ private:
friend class QGLWidget;
friend class QGLWidgetPrivate;
friend class QGLGlyphCache;
friend class QOpenGLPaintEngine;
friend class QOpenGLPaintEnginePrivate;
friend class QGL2PaintEngineEx;
friend class QGL2PaintEngineExPrivate;
friend class QGLEngineShaderManager;
friend class QGLPixmapFilterBase;
friend class QGLTextureGlyphCache;
friend struct QGLGlyphTexture;
friend class QGLContextGroup;
@ -553,22 +479,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
GLuint bindTexture(const QImage &image, QMacCompatGLenum = GL_TEXTURE_2D,
QMacCompatGLint format = GL_RGBA);
GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum = GL_TEXTURE_2D,
QMacCompatGLint format = GL_RGBA);
GLuint bindTexture(const QImage &image, QMacCompatGLenum, QMacCompatGLint format,
QGLContext::BindOptions);
GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum, QMacCompatGLint format,
QGLContext::BindOptions);
void deleteTexture(QMacCompatGLuint tx_id);
void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
#endif
public Q_SLOTS:
virtual void updateGL();
virtual void updateOverlayGL();
@ -610,7 +520,6 @@ private:
friend class QGLContext;
friend class QGLContextPrivate;
friend class QGLOverlayWidget;
friend class QOpenGLPaintEngine;
friend class QGLPaintDevice;
friend class QGLWidgetGLPaintDevice;
};

View File

@ -1,350 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/qdebug.h>
#include <QtOpenGL/qgl.h>
#include <QtOpenGL/qglpixelbuffer.h>
#include "qgl_p.h"
#include "qgl_egl_p.h"
#include "qglpixelbuffer_p.h"
#ifdef Q_WS_X11
#include <QtGui/private/qpixmap_x11_p.h>
#endif
QT_BEGIN_NAMESPACE
QEglProperties *QGLContextPrivate::extraWindowSurfaceCreationProps = NULL;
void qt_eglproperties_set_glformat(QEglProperties& eglProperties, const QGLFormat& glFormat)
{
int redSize = glFormat.redBufferSize();
int greenSize = glFormat.greenBufferSize();
int blueSize = glFormat.blueBufferSize();
int alphaSize = glFormat.alphaBufferSize();
int depthSize = glFormat.depthBufferSize();
int stencilSize = glFormat.stencilBufferSize();
int sampleCount = glFormat.samples();
// QGLFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that
// type has been requested. So we must check QGLFormat's booleans too if size is -1:
if (glFormat.alpha() && alphaSize <= 0)
alphaSize = 1;
if (glFormat.depth() && depthSize <= 0)
depthSize = 1;
if (glFormat.stencil() && stencilSize <= 0)
stencilSize = 1;
if (glFormat.sampleBuffers() && sampleCount <= 0)
sampleCount = 1;
// We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide
// the best performance. The EGL config selection algorithm is a bit stange in this regard:
// The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard
// 32-bit configs completely from the selection. So it then comes to the sorting algorithm.
// The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort
// order is special and described as "by larger _total_ number of color bits.". So EGL will
// put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on
// to say "If the requested number of bits in attrib_list for a particular component is 0,
// then the number of bits for that component is not considered". This part of the spec also
// seems to imply that setting the red/green/blue bits to zero means none of the components
// are considered and EGL disregards the entire sorting rule. It then looks to the next
// highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being
// "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are
// put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit,
// we must set the red/green/blue sizes to zero. This has an unfortunate consequence that
// if the application sets the red/green/blue size to 5/6/5 on the QGLFormat, they will
// probably get a 32-bit config, even when there's an RGB565 config available. Oh well.
// Now normalize the values so -1 becomes 0
redSize = redSize > 0 ? redSize : 0;
greenSize = greenSize > 0 ? greenSize : 0;
blueSize = blueSize > 0 ? blueSize : 0;
alphaSize = alphaSize > 0 ? alphaSize : 0;
depthSize = depthSize > 0 ? depthSize : 0;
stencilSize = stencilSize > 0 ? stencilSize : 0;
sampleCount = sampleCount > 0 ? sampleCount : 0;
eglProperties.setValue(EGL_RED_SIZE, redSize);
eglProperties.setValue(EGL_GREEN_SIZE, greenSize);
eglProperties.setValue(EGL_BLUE_SIZE, blueSize);
eglProperties.setValue(EGL_ALPHA_SIZE, alphaSize);
eglProperties.setValue(EGL_DEPTH_SIZE, depthSize);
eglProperties.setValue(EGL_STENCIL_SIZE, stencilSize);
eglProperties.setValue(EGL_SAMPLES, sampleCount);
eglProperties.setValue(EGL_SAMPLE_BUFFERS, sampleCount ? 1 : 0);
}
// Updates "format" with the parameters of the selected configuration.
void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config)
{
EGLint redSize = 0;
EGLint greenSize = 0;
EGLint blueSize = 0;
EGLint alphaSize = 0;
EGLint depthSize = 0;
EGLint stencilSize = 0;
EGLint sampleCount = 0;
EGLint level = 0;
EGLDisplay display = QEgl::display();
eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize);
eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize);
eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize);
eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize);
eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize);
eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount);
eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
format.setRedBufferSize(redSize);
format.setGreenBufferSize(greenSize);
format.setBlueBufferSize(blueSize);
format.setAlphaBufferSize(alphaSize);
format.setDepthBufferSize(depthSize);
format.setStencilBufferSize(stencilSize);
format.setSamples(sampleCount);
format.setPlane(level);
format.setDirectRendering(true); // All EGL contexts are direct-rendered
format.setRgba(true); // EGL doesn't support colour index rendering
format.setStereo(false); // EGL doesn't support stereo buffers
format.setAccumBufferSize(0); // EGL doesn't support accululation buffers
format.setDoubleBuffer(true); // We don't support single buffered EGL contexts
// Clear the EGL error state because some of the above may
// have errored out because the attribute is not applicable
// to the surface type. Such errors don't matter.
eglGetError();
}
bool QGLFormat::hasOpenGL()
{
return true;
}
void QGLContext::reset()
{
Q_D(QGLContext);
if (!d->valid)
return;
d->cleanup();
doneCurrent();
if (d->eglContext && d->ownsEglContext) {
d->destroyEglSurfaceForDevice();
delete d->eglContext;
}
d->ownsEglContext = false;
d->eglContext = 0;
d->eglSurface = EGL_NO_SURFACE;
d->crWin = false;
d->sharing = false;
d->valid = false;
d->transpColor = QColor();
d->initDone = false;
QGLContextGroup::removeShare(this);
}
void QGLContext::makeCurrent()
{
Q_D(QGLContext);
if (!d->valid || !d->eglContext || d->eglSurfaceForDevice() == EGL_NO_SURFACE) {
qWarning("QGLContext::makeCurrent(): Cannot make invalid context current");
return;
}
if (d->eglContext->makeCurrent(d->eglSurfaceForDevice())) {
QGLContextPrivate::setCurrentContext(this);
if (!d->workaroundsCached) {
d->workaroundsCached = true;
const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
if (renderer && (strstr(renderer, "SGX") || strstr(renderer, "MBX"))) {
// PowerVR MBX/SGX chips needs to clear all buffers when starting to render
// a new frame, otherwise there will be a performance penalty to pay for
// each frame.
qDebug() << "Found SGX/MBX driver, enabling FullClearOnEveryFrame";
d->workaround_needsFullClearOnEveryFrame = true;
// Older PowerVR SGX drivers (like the one in the N900) have a
// bug which prevents glCopyTexSubImage2D() to work with a POT
// or GL_ALPHA texture bound to an FBO. The only way to
// identify that driver is to check the EGL version number for it.
const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION);
if (egl_version && strstr(egl_version, "1.3")) {
qDebug() << "Found v1.3 driver, enabling brokenFBOReadBack";
d->workaround_brokenFBOReadBack = true;
} else if (egl_version && strstr(egl_version, "1.4")) {
qDebug() << "Found v1.4 driver, enabling brokenTexSubImage";
d->workaround_brokenTexSubImage = true;
// this is a bit complicated; 1.4 version SGX drivers from
// Nokia have fixed the brokenFBOReadBack problem, but
// official drivers from TI haven't, meaning that things
// like the beagleboard are broken unless we hack around it
// - but at the same time, we want to not reduce performance
// by not enabling this elsewhere.
//
// so, let's check for a Nokia-specific addon, and only
// enable if it isn't present.
// (see MeeGo bug #5616)
if (!QEgl::hasExtension("EGL_NOK_image_shared")) {
// no Nokia extension, this is probably a standard SGX
// driver, so enable the workaround
qDebug() << "Found non-Nokia v1.4 driver, enabling brokenFBOReadBack";
d->workaround_brokenFBOReadBack = true;
}
}
}
}
}
}
void QGLContext::doneCurrent()
{
Q_D(QGLContext);
if (d->eglContext)
d->eglContext->doneCurrent();
QGLContextPrivate::setCurrentContext(0);
}
void QGLContext::swapBuffers() const
{
Q_D(const QGLContext);
if (!d->valid || !d->eglContext)
return;
d->eglContext->swapBuffers(d->eglSurfaceForDevice());
}
void QGLContextPrivate::destroyEglSurfaceForDevice()
{
if (eglSurface != EGL_NO_SURFACE) {
#if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN)
// Make sure we don't call eglDestroySurface on a surface which
// was created for a different winId. This applies only to QGLWidget
// paint device, so make sure this is the one we're operating on.
if (paintDevice && paintDevice->devType() == QInternal::Widget) {
QWidget *w = static_cast<QWidget *>(paintDevice);
if (QGLWidget *wgl = qobject_cast<QGLWidget *>(w)) {
if (wgl->d_func()->eglSurfaceWindowId != wgl->winId()) {
qWarning("WARNING: Potential EGL surface leak! Not destroying surface.");
eglSurface = EGL_NO_SURFACE;
return;
}
}
}
#endif
eglDestroySurface(eglContext->display(), eglSurface);
eglSurface = EGL_NO_SURFACE;
}
}
EGLSurface QGLContextPrivate::eglSurfaceForDevice() const
{
// If a QPlatformPixmap had to create the QGLContext, we don't have a paintDevice
if (!paintDevice)
return eglSurface;
#ifdef Q_WS_X11
if (paintDevice->devType() == QInternal::Pixmap) {
QPlatformPixmap *pmd = static_cast<QPixmap*>(paintDevice)->data_ptr().data();
if (pmd->classId() == QPlatformPixmap::X11Class) {
QX11PlatformPixmap* x11PlatformPixmap = static_cast<QX11PlatformPixmap*>(pmd);
return (EGLSurface)x11PlatformPixmap->gl_surface;
}
}
#endif
if (paintDevice->devType() == QInternal::Pbuffer) {
QGLPixelBuffer* pbuf = static_cast<QGLPixelBuffer*>(paintDevice);
return pbuf->d_func()->pbuf;
}
return eglSurface;
}
void QGLContextPrivate::swapRegion(const QRegion &region)
{
if (!valid || !eglContext)
return;
eglContext->swapBuffersRegion2NOK(eglSurfaceForDevice(), &region);
}
void QGLContextPrivate::setExtraWindowSurfaceCreationProps(QEglProperties *props)
{
extraWindowSurfaceCreationProps = props;
}
void QGLWidget::setMouseTracking(bool enable)
{
QWidget::setMouseTracking(enable);
}
QColor QGLContext::overlayTransparentColor() const
{
return d_func()->transpColor;
}
uint QGLContext::colorIndex(const QColor &c) const
{
Q_UNUSED(c);
return 0;
}
void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
{
Q_UNUSED(fnt);
Q_UNUSED(listBase);
}
void *QGLContext::getProcAddress(const QString &proc) const
{
return (void*)eglGetProcAddress(reinterpret_cast<const char *>(proc.toLatin1().data()));
}
bool QGLWidgetPrivate::renderCxPm(QPixmap*)
{
return false;
}
QT_END_NAMESPACE

View File

@ -1,69 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QGL_EGL_P_H
#define QGL_EGL_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of the QGLWidget class. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include <QtGui/private/qegl_p.h>
#include <QtGui/private/qeglcontext_p.h>
#include <QtGui/private/qeglproperties_p.h>
QT_BEGIN_NAMESPACE
class QGLFormat;
void qt_eglproperties_set_glformat(QEglProperties& props, const QGLFormat& format);
void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config);
QT_END_NAMESPACE
#endif // QGL_EGL_P_H

View File

@ -1,996 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qgl.h"
// There are functions that are deprecated in 10.5, but really there's no way around them
// for Carbon, so just undefine them.
#undef DEPRECATED_ATTRIBUTE
#define DEPRECATED_ATTRIBUTE
#if defined(Q_WS_MAC)
#ifndef QT_MAC_USE_COCOA
#ifdef qDebug
# undef qDebug
# include <AGL/agl.h>
# include <AGL/aglRenderers.h>
# include <OpenGL/gl.h>
# ifdef QT_NO_DEBUG
# define qDebug qt_noop(),1?(void)0:qDebug
# endif
#else
# include <AGL/agl.h>
# include <AGL/aglRenderers.h>
# include <OpenGL/gl.h>
#endif
#else
#include <private/qcocoaview_mac_p.h>
#endif
#include <OpenGL/gl.h>
#include <CoreServices/CoreServices.h>
#include <private/qfont_p.h>
#include <private/qfontengine_p.h>
#include <private/qgl_p.h>
#include <private/qpaintengine_opengl_p.h>
#include <private/qt_mac_p.h>
#include <qpixmap.h>
#include <qtimer.h>
#include <qapplication.h>
#include <qstack.h>
#include <qdesktopwidget.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
#ifdef QT_MAC_USE_COCOA
QT_END_NAMESPACE
QT_FORWARD_DECLARE_CLASS(QWidget)
QT_FORWARD_DECLARE_CLASS(QWidgetPrivate)
QT_FORWARD_DECLARE_CLASS(QGLWidgetPrivate)
QT_BEGIN_NAMESPACE
void *qt_current_nsopengl_context()
{
return [NSOpenGLContext currentContext];
}
static GLint attribValue(NSOpenGLPixelFormat *fmt, NSOpenGLPixelFormatAttribute attrib)
{
GLint res;
[fmt getValues:&res forAttribute:attrib forVirtualScreen:0];
return res;
}
static int def(int val, int defVal)
{
return val != -1 ? val : defVal;
}
#else
QRegion qt_mac_get_widget_rgn(const QWidget *widget);
#endif
extern quint32 *qt_mac_pixmap_get_base(const QPixmap *);
extern int qt_mac_pixmap_get_bytes_per_line(const QPixmap *);
extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
extern void qt_mac_dispose_rgn(RgnHandle); //qregion_mac.cpp
extern QRegion qt_mac_convert_mac_region(RgnHandle); //qregion_mac.cpp
extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); //qglobal.cpp
/*
QGLTemporaryContext implementation
*/
class QGLTemporaryContextPrivate
{
public:
#ifndef QT_MAC_USE_COCOA
AGLContext ctx;
#else
NSOpenGLContext *ctx;
#endif
};
QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
: d(new QGLTemporaryContextPrivate)
{
d->ctx = 0;
#ifndef QT_MAC_USE_COCOA
GLint attribs[] = {AGL_RGBA, AGL_NONE};
AGLPixelFormat fmt = aglChoosePixelFormat(0, 0, attribs);
if (!fmt) {
qDebug("QGLTemporaryContext: Couldn't find any RGB visuals");
return;
}
d->ctx = aglCreateContext(fmt, 0);
if (!d->ctx)
qDebug("QGLTemporaryContext: Unable to create context");
else
aglSetCurrentContext(d->ctx);
aglDestroyPixelFormat(fmt);
#else
QMacCocoaAutoReleasePool pool;
NSOpenGLPixelFormatAttribute attribs[] = { 0 };
NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
if (!fmt) {
qWarning("QGLTemporaryContext: Cannot find any visuals");
return;
}
d->ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:0];
if (!d->ctx)
qWarning("QGLTemporaryContext: Cannot create context");
else
[d->ctx makeCurrentContext];
[fmt release];
#endif
}
QGLTemporaryContext::~QGLTemporaryContext()
{
if (d->ctx) {
#ifndef QT_MAC_USE_COCOA
aglSetCurrentContext(0);
aglDestroyContext(d->ctx);
#else
[NSOpenGLContext clearCurrentContext];
[d->ctx release];
#endif
}
}
bool QGLFormat::hasOpenGL()
{
return true;
}
bool QGLFormat::hasOpenGLOverlays()
{
return false;
}
bool QGLContext::chooseContext(const QGLContext *shareContext)
{
QMacCocoaAutoReleasePool pool;
Q_D(QGLContext);
d->cx = 0;
d->vi = chooseMacVisual(0);
if (!d->vi)
return false;
#ifndef QT_MAC_USE_COCOA
AGLPixelFormat fmt = (AGLPixelFormat)d->vi;
GLint res;
aglDescribePixelFormat(fmt, AGL_LEVEL, &res);
d->glFormat.setPlane(res);
if (deviceIsPixmap())
res = 0;
else
aglDescribePixelFormat(fmt, AGL_DOUBLEBUFFER, &res);
d->glFormat.setDoubleBuffer(res);
aglDescribePixelFormat(fmt, AGL_DEPTH_SIZE, &res);
d->glFormat.setDepth(res);
if (d->glFormat.depth())
d->glFormat.setDepthBufferSize(res);
aglDescribePixelFormat(fmt, AGL_RGBA, &res);
d->glFormat.setRgba(res);
aglDescribePixelFormat(fmt, AGL_RED_SIZE, &res);
d->glFormat.setRedBufferSize(res);
aglDescribePixelFormat(fmt, AGL_GREEN_SIZE, &res);
d->glFormat.setGreenBufferSize(res);
aglDescribePixelFormat(fmt, AGL_BLUE_SIZE, &res);
d->glFormat.setBlueBufferSize(res);
aglDescribePixelFormat(fmt, AGL_ALPHA_SIZE, &res);
d->glFormat.setAlpha(res);
if (d->glFormat.alpha())
d->glFormat.setAlphaBufferSize(res);
aglDescribePixelFormat(fmt, AGL_ACCUM_RED_SIZE, &res);
// Bug in Apple OpenGL (rdr://5015603), when we don't have an accumulation
// buffer, it still claims that we have a 16-bit one (which is pretty rare).
// So, we just assume we can never have a buffer that small.
d->glFormat.setAccum(res > 5);
if (d->glFormat.accum())
d->glFormat.setAccumBufferSize(res);
aglDescribePixelFormat(fmt, AGL_STENCIL_SIZE, &res);
d->glFormat.setStencil(res);
if (d->glFormat.stencil())
d->glFormat.setStencilBufferSize(res);
aglDescribePixelFormat(fmt, AGL_STEREO, &res);
d->glFormat.setStereo(res);
aglDescribePixelFormat(fmt, AGL_SAMPLE_BUFFERS_ARB, &res);
d->glFormat.setSampleBuffers(res);
if (d->glFormat.sampleBuffers()) {
aglDescribePixelFormat(fmt, AGL_SAMPLES_ARB, &res);
d->glFormat.setSamples(res);
}
#else
NSOpenGLPixelFormat *fmt = static_cast<NSOpenGLPixelFormat *>(d->vi);
d->glFormat = QGLFormat();
// ### make sure to reset other options
d->glFormat.setDoubleBuffer(attribValue(fmt, NSOpenGLPFADoubleBuffer));
int depthSize = attribValue(fmt, NSOpenGLPFADepthSize);
d->glFormat.setDepth(depthSize > 0);
if (depthSize > 0)
d->glFormat.setDepthBufferSize(depthSize);
int alphaSize = attribValue(fmt, NSOpenGLPFAAlphaSize);
d->glFormat.setAlpha(alphaSize > 0);
if (alphaSize > 0)
d->glFormat.setAlphaBufferSize(alphaSize);
int accumSize = attribValue(fmt, NSOpenGLPFAAccumSize);
d->glFormat.setAccum(accumSize > 0);
if (accumSize > 0)
d->glFormat.setAccumBufferSize(accumSize);
int stencilSize = attribValue(fmt, NSOpenGLPFAStencilSize);
d->glFormat.setStencil(stencilSize > 0);
if (stencilSize > 0)
d->glFormat.setStencilBufferSize(stencilSize);
d->glFormat.setStereo(attribValue(fmt, NSOpenGLPFAStereo));
int sampleBuffers = attribValue(fmt, NSOpenGLPFASampleBuffers);
d->glFormat.setSampleBuffers(sampleBuffers);
if (sampleBuffers > 0)
d->glFormat.setSamples(attribValue(fmt, NSOpenGLPFASamples));
#endif
if (shareContext && (!shareContext->isValid() || !shareContext->d_func()->cx)) {
qWarning("QGLContext::chooseContext: Cannot share with invalid context");
shareContext = 0;
}
// sharing between rgba and color-index will give wrong colors
if (shareContext && (format().rgba() != shareContext->format().rgba()))
shareContext = 0;
#ifndef QT_MAC_USE_COCOA
AGLContext ctx = aglCreateContext(fmt, (AGLContext) (shareContext ? shareContext->d_func()->cx : 0));
#else
NSOpenGLContext *ctx = [[NSOpenGLContext alloc] initWithFormat:fmt
shareContext:(shareContext ? static_cast<NSOpenGLContext *>(shareContext->d_func()->cx)
: 0)];
#endif
if (!ctx) {
#ifndef QT_MAC_USE_COCOA
GLenum err = aglGetError();
if (err == AGL_BAD_MATCH || err == AGL_BAD_CONTEXT) {
if (shareContext && shareContext->d_func()->cx) {
qWarning("QGLContext::chooseContext(): Context sharing mismatch!");
if (!(ctx = aglCreateContext(fmt, 0)))
return false;
shareContext = 0;
}
}
#else
if (shareContext) {
ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:0];
if (ctx) {
qWarning("QGLContext::chooseContext: Context sharing mismatch");
shareContext = 0;
}
}
#endif
if (!ctx) {
qWarning("QGLContext::chooseContext: Unable to create QGLContext");
return false;
}
}
d->cx = ctx;
if (shareContext && shareContext->d_func()->cx) {
QGLContext *share = const_cast<QGLContext *>(shareContext);
d->sharing = true;
share->d_func()->sharing = true;
}
if (deviceIsPixmap())
updatePaintDevice();
// vblank syncing
GLint interval = d->reqFormat.swapInterval();
if (interval != -1) {
#ifndef QT_MAC_USE_COCOA
aglSetInteger((AGLContext)d->cx, AGL_SWAP_INTERVAL, &interval);
if (interval != 0)
aglEnable((AGLContext)d->cx, AGL_SWAP_INTERVAL);
else
aglDisable((AGLContext)d->cx, AGL_SWAP_INTERVAL);
#else
[ctx setValues:&interval forParameter:NSOpenGLCPSwapInterval];
#endif
}
#ifndef QT_MAC_USE_COCOA
aglGetInteger((AGLContext)d->cx, AGL_SWAP_INTERVAL, &interval);
#else
[ctx getValues:&interval forParameter:NSOpenGLCPSwapInterval];
#endif
d->glFormat.setSwapInterval(interval);
return true;
}
void *QGLContextPrivate::tryFormat(const QGLFormat &format)
{
static const int Max = 40;
#ifndef QT_MAC_USE_COCOA
GLint attribs[Max], cnt = 0;
bool device_is_pixmap = (paintDevice->devType() == QInternal::Pixmap);
attribs[cnt++] = AGL_RGBA;
attribs[cnt++] = AGL_BUFFER_SIZE;
attribs[cnt++] = device_is_pixmap ? static_cast<QPixmap *>(paintDevice)->depth() : 32;
attribs[cnt++] = AGL_LEVEL;
attribs[cnt++] = format.plane();
if (format.redBufferSize() != -1) {
attribs[cnt++] = AGL_RED_SIZE;
attribs[cnt++] = format.redBufferSize();
}
if (format.greenBufferSize() != -1) {
attribs[cnt++] = AGL_GREEN_SIZE;
attribs[cnt++] = format.greenBufferSize();
}
if (format.blueBufferSize() != -1) {
attribs[cnt++] = AGL_BLUE_SIZE;
attribs[cnt++] = format.blueBufferSize();
}
if (device_is_pixmap) {
attribs[cnt++] = AGL_PIXEL_SIZE;
attribs[cnt++] = static_cast<QPixmap *>(paintDevice)->depth();
attribs[cnt++] = AGL_OFFSCREEN;
if (!format.alpha()) {
attribs[cnt++] = AGL_ALPHA_SIZE;
attribs[cnt++] = 8;
}
} else {
if (format.doubleBuffer())
attribs[cnt++] = AGL_DOUBLEBUFFER;
}
if (format.stereo())
attribs[cnt++] = AGL_STEREO;
if (format.alpha()) {
attribs[cnt++] = AGL_ALPHA_SIZE;
attribs[cnt++] = format.alphaBufferSize() == -1 ? 8 : format.alphaBufferSize();
}
if (format.stencil()) {
attribs[cnt++] = AGL_STENCIL_SIZE;
attribs[cnt++] = format.stencilBufferSize() == -1 ? 8 : format.stencilBufferSize();
}
if (format.depth()) {
attribs[cnt++] = AGL_DEPTH_SIZE;
attribs[cnt++] = format.depthBufferSize() == -1 ? 32 : format.depthBufferSize();
}
if (format.accum()) {
attribs[cnt++] = AGL_ACCUM_RED_SIZE;
attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
attribs[cnt++] = AGL_ACCUM_BLUE_SIZE;
attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
attribs[cnt++] = AGL_ACCUM_GREEN_SIZE;
attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
attribs[cnt++] = AGL_ACCUM_ALPHA_SIZE;
attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
}
if (format.sampleBuffers()) {
attribs[cnt++] = AGL_SAMPLE_BUFFERS_ARB;
attribs[cnt++] = 1;
attribs[cnt++] = AGL_SAMPLES_ARB;
attribs[cnt++] = format.samples() == -1 ? 4 : format.samples();
}
attribs[cnt] = AGL_NONE;
Q_ASSERT(cnt < Max);
return aglChoosePixelFormat(0, 0, attribs);
#else
NSOpenGLPixelFormatAttribute attribs[Max];
int cnt = 0;
int devType = paintDevice->devType();
bool device_is_pixmap = (devType == QInternal::Pixmap);
int depth = device_is_pixmap ? static_cast<QPixmap *>(paintDevice)->depth() : 32;
attribs[cnt++] = NSOpenGLPFAColorSize;
attribs[cnt++] = depth;
if (device_is_pixmap) {
attribs[cnt++] = NSOpenGLPFAOffScreen;
} else {
if (format.doubleBuffer())
attribs[cnt++] = NSOpenGLPFADoubleBuffer;
}
if (glFormat.stereo())
attribs[cnt++] = NSOpenGLPFAStereo;
if (device_is_pixmap || format.alpha()) {
attribs[cnt++] = NSOpenGLPFAAlphaSize;
attribs[cnt++] = def(format.alphaBufferSize(), 8);
}
if (format.stencil()) {
attribs[cnt++] = NSOpenGLPFAStencilSize;
attribs[cnt++] = def(format.stencilBufferSize(), 8);
}
if (format.depth()) {
attribs[cnt++] = NSOpenGLPFADepthSize;
attribs[cnt++] = def(format.depthBufferSize(), 32);
}
if (format.accum()) {
attribs[cnt++] = NSOpenGLPFAAccumSize;
attribs[cnt++] = def(format.accumBufferSize(), 1);
}
if (format.sampleBuffers()) {
attribs[cnt++] = NSOpenGLPFASampleBuffers;
attribs[cnt++] = 1;
attribs[cnt++] = NSOpenGLPFASamples;
attribs[cnt++] = def(format.samples(), 4);
}
if (format.directRendering())
attribs[cnt++] = NSOpenGLPFAAccelerated;
if (devType == QInternal::Pbuffer)
attribs[cnt++] = NSOpenGLPFAPixelBuffer;
attribs[cnt] = 0;
Q_ASSERT(cnt < Max);
return [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
#endif
}
void QGLContextPrivate::clearDrawable()
{
[static_cast<NSOpenGLContext *>(cx) clearDrawable];
}
/*!
\bold{Mac OS X only:} This virtual function tries to find a visual that
matches the format, reducing the demands if the original request
cannot be met.
The algorithm for reducing the demands of the format is quite
simple-minded, so override this method in your subclass if your
application has spcific requirements on visual selection.
The \a handle argument is always zero and is not used
\sa chooseContext()
*/
void *QGLContext::chooseMacVisual(GDHandle /* handle */)
{
Q_D(QGLContext);
void *fmt = d->tryFormat(d->glFormat);
if (!fmt && d->glFormat.stereo()) {
d->glFormat.setStereo(false);
fmt = d->tryFormat(d->glFormat);
}
if (!fmt && d->glFormat.sampleBuffers()) {
d->glFormat.setSampleBuffers(false);
fmt = d->tryFormat(d->glFormat);
}
if (!fmt)
qWarning("QGLContext::chooseMacVisual: Unable to choose a pixel format");
return fmt;
}
void QGLContext::reset()
{
Q_D(QGLContext);
if (!d->valid)
return;
d->cleanup();
doneCurrent();
#ifndef QT_MAC_USE_COCOA
if (d->cx)
aglDestroyContext((AGLContext)d->cx);
#else
QMacCocoaAutoReleasePool pool;
[static_cast<NSOpenGLContext *>(d->cx) release];
#endif
d->cx = 0;
#ifndef QT_MAC_USE_COCOA
if (d->vi)
aglDestroyPixelFormat((AGLPixelFormat)d->vi);
#else
[static_cast<NSOpenGLPixelFormat *>(d->vi) release];
#endif
d->vi = 0;
d->crWin = false;
d->sharing = false;
d->valid = false;
d->transpColor = QColor();
d->initDone = false;
QGLContextGroup::removeShare(this);
}
void QGLContext::makeCurrent()
{
Q_D(QGLContext);
if (!d->valid) {
qWarning("QGLContext::makeCurrent: Cannot make invalid context current");
return;
}
#ifndef QT_MAC_USE_COCOA
aglSetCurrentContext((AGLContext)d->cx);
if (d->update)
updatePaintDevice();
#else
[static_cast<NSOpenGLContext *>(d->cx) makeCurrentContext];
#endif
QGLContextPrivate::setCurrentContext(this);
}
#ifndef QT_MAC_USE_COCOA
/*
Returns the effective scale factor for a widget. For this value to be
different than 1, the following must be true:
- The system scale factor must be greater than 1.
- The widget window must have WA_MacFrameworkScaled set.
*/
float qt_mac_get_scale_factor(QWidget *widget)
{
if (!widget | !widget->window())
return 1;
if (widget->window()->testAttribute(Qt::WA_MacFrameworkScaled) == false)
return 1;
float systemScale = QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4 ? HIGetScaleFactor() : 1;
if (systemScale == float(1))
return 1;
return systemScale;
}
#endif
/*! \internal
*/
void QGLContext::updatePaintDevice()
{
Q_D(QGLContext);
#ifndef QT_MAC_USE_COCOA
d->update = false;
if (d->paintDevice->devType() == QInternal::Widget) {
//get control information
QWidget *w = (QWidget *)d->paintDevice;
HIViewRef hiview = (HIViewRef)w->winId();
WindowRef window = HIViewGetWindow(hiview);
#ifdef DEBUG_OPENGL_REGION_UPDATE
static int serial_no_gl = 0;
qDebug("[%d] %p setting on %s::%s %p/%p [%s]", ++serial_no_gl, w,
w->metaObject()->className(), w->objectName().toLatin1().constData(),
hiview, window, w->handle() ? "Inside" : "Outside");
#endif
//update drawable
if (0 && w->isWindow() && w->isFullScreen()) {
aglSetDrawable((AGLContext)d->cx, 0);
aglSetFullScreen((AGLContext)d->cx, w->width(), w->height(), 0, QApplication::desktop()->screenNumber(w));
w->hide();
} else {
AGLDrawable old_draw = aglGetDrawable((AGLContext)d->cx), new_draw = GetWindowPort(window);
if (old_draw != new_draw)
aglSetDrawable((AGLContext)d->cx, new_draw);
}
float scale = qt_mac_get_scale_factor(w);
if (!w->isWindow()) {
QRegion clp = qt_mac_get_widget_rgn(w); //get drawable area
#ifdef DEBUG_OPENGL_REGION_UPDATE
if (clp.isEmpty()) {
qDebug(" Empty area!");
} else {
QVector<QRect> rs = clp.rects();
for(int i = 0; i < rs.count(); i++)
qDebug(" %d %d %d %d", rs[i].x(), rs[i].y(), rs[i].width(), rs[i].height());
}
#endif
//update the clip
if (!aglIsEnabled((AGLContext)d->cx, AGL_BUFFER_RECT))
aglEnable((AGLContext)d->cx, AGL_BUFFER_RECT);
if (clp.isEmpty()) {
GLint offs[4] = { 0, 0, 0, 0 };
aglSetInteger((AGLContext)d->cx, AGL_BUFFER_RECT, offs);
if (aglIsEnabled((AGLContext)d->cx, AGL_CLIP_REGION))
aglDisable((AGLContext)d->cx, AGL_CLIP_REGION);
} else {
HIPoint origin = { 0., 0. };
HIViewConvertPoint(&origin, HIViewRef(w->winId()), 0);
const GLint offs[4] = { qRound(origin.x),
w->window()->frameGeometry().height() * scale
- (qRound(origin.y) + w->height() * scale),
w->width() * scale, w->height() * scale};
RgnHandle region = clp.handle(true);
if (scale != float(1)) {
// Sacle the clip region by the scale factor
Rect regionBounds;
GetRegionBounds(region, &regionBounds);
Rect regionBoundsDest = regionBounds;
regionBoundsDest.bottom *= scale;
regionBoundsDest.right *= scale;
MapRgn(region, &regionBounds, &regionBoundsDest);
}
aglSetInteger((AGLContext)d->cx, AGL_BUFFER_RECT, offs);
aglSetInteger((AGLContext)d->cx, AGL_CLIP_REGION, (const GLint *)region);
if (!aglIsEnabled((AGLContext)d->cx, AGL_CLIP_REGION))
aglEnable((AGLContext)d->cx, AGL_CLIP_REGION);
}
} else {
// Set the buffer rect for top-level gl contexts when scaled.
if (scale != float(1)) {
aglEnable((AGLContext)d->cx, AGL_BUFFER_RECT);
const GLint offs[4] = { 0, 0, w->width() * scale , w->height() * scale};
aglSetInteger((AGLContext)d->cx, AGL_BUFFER_RECT, offs);
}
}
} else if (d->paintDevice->devType() == QInternal::Pixmap) {
QPixmap *pm = reinterpret_cast<QPixmap *>(d->paintDevice);
unsigned long qdformat = k32ARGBPixelFormat;
if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
qdformat = k32BGRAPixelFormat;
Rect rect;
SetRect(&rect, 0, 0, pm->width(), pm->height());
GWorldPtr gworld;
NewGWorldFromPtr(&gworld, qdformat, &rect, 0, 0, 0,
reinterpret_cast<char *>(qt_mac_pixmap_get_base(pm)),
qt_mac_pixmap_get_bytes_per_line(pm));
PixMapHandle pixmapHandle = GetGWorldPixMap(gworld);
aglSetOffScreen(reinterpret_cast<AGLContext>(d->cx), pm->width(), pm->height(),
GetPixRowBytes(pixmapHandle), GetPixBaseAddr(pixmapHandle));
} else {
qWarning("QGLContext::updatePaintDevice(): Not sure how to render OpenGL on this device!");
}
aglUpdateContext((AGLContext)d->cx);
#else
QMacCocoaAutoReleasePool pool;
if (d->paintDevice->devType() == QInternal::Widget) {
//get control information
QWidget *w = (QWidget *)d->paintDevice;
NSView *view = qt_mac_nativeview_for(w);
// Trying to attach the GL context to the NSView will fail with
// "invalid drawable" if done too soon, but we have to make sure
// the connection is made before the first paint event. Using
// the NSView do to this check fails as the NSView is visible
// before it's safe to connect, and using the NSWindow fails as
// the NSWindow will become visible after the first paint event.
// This leaves us with the QWidget, who's visible state seems
// to match the point in time when it's safe to connect.
if (!w || !w->isVisible())
return; // Not safe to attach GL context to view yet
if ([static_cast<NSOpenGLContext *>(d->cx) view] != view && ![view isHidden])
[static_cast<NSOpenGLContext *>(d->cx) setView:view];
} else if (d->paintDevice->devType() == QInternal::Pixmap) {
const QPixmap *pm = static_cast<const QPixmap *>(d->paintDevice);
[static_cast<NSOpenGLContext *>(d->cx) setOffScreen:qt_mac_pixmap_get_base(pm)
width:pm->width()
height:pm->height()
rowbytes:qt_mac_pixmap_get_bytes_per_line(pm)];
} else {
qWarning("QGLContext::updatePaintDevice: Not sure how to render OpenGL on this device");
}
[static_cast<NSOpenGLContext *>(d->cx) update];
#endif
}
void QGLContext::doneCurrent()
{
if (
#ifndef QT_MAC_USE_COCOA
aglGetCurrentContext() != (AGLContext) d_func()->cx
#else
[NSOpenGLContext currentContext] != d_func()->cx
#endif
)
return;
QGLContextPrivate::setCurrentContext(0);
#ifndef QT_MAC_USE_COCOA
aglSetCurrentContext(0);
#else
[NSOpenGLContext clearCurrentContext];
#endif
}
void QGLContext::swapBuffers() const
{
Q_D(const QGLContext);
if (!d->valid)
return;
#ifndef QT_MAC_USE_COCOA
aglSwapBuffers((AGLContext)d->cx);
#else
[static_cast<NSOpenGLContext *>(d->cx) flushBuffer];
#endif
}
QColor QGLContext::overlayTransparentColor() const
{
return QColor(0, 0, 0); // Invalid color
}
#ifndef QT_MAC_USE_COCOA
static QColor cmap[256];
static bool cmap_init = false;
#endif
uint QGLContext::colorIndex(const QColor &c) const
{
#ifndef QT_MAC_USE_COCOA
int ret = -1;
if(!cmap_init) {
cmap_init = true;
for(int i = 0; i < 256; i++)
cmap[i] = QColor();
} else {
for(int i = 0; i < 256; i++) {
if(cmap[i].isValid() && cmap[i] == c) {
ret = i;
break;
}
}
}
if(ret == -1) {
for(ret = 0; ret < 256; ret++)
if(!cmap[ret].isValid())
break;
if(ret == 256) {
ret = -1;
qWarning("QGLContext::colorIndex(): Internal error!");
} else {
cmap[ret] = c;
GLint vals[4];
vals[0] = ret;
vals[1] = c.red();
vals[2] = c.green();
vals[3] = c.blue();
aglSetInteger((AGLContext)d_func()->cx, AGL_COLORMAP_ENTRY, vals);
}
}
return (uint)(ret == -1 ? 0 : ret);
#else
Q_UNUSED(c);
return 0;
#endif
}
void QGLContext::generateFontDisplayLists(const QFont & /* fnt */, int /* listBase */)
{
}
static CFBundleRef qt_getOpenGLBundle()
{
CFBundleRef bundle = 0;
CFStringRef urlString = QCFString::toCFStringRef(QLatin1String("/System/Library/Frameworks/OpenGL.framework"));
QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
urlString, kCFURLPOSIXPathStyle, false);
if (url)
bundle = CFBundleCreate(kCFAllocatorDefault, url);
CFRelease(urlString);
return bundle;
}
void *QGLContext::getProcAddress(const QString &proc) const
{
CFStringRef procName = QCFString(proc).toCFStringRef(proc);
void *result = CFBundleGetFunctionPointerForName(QCFType<CFBundleRef>(qt_getOpenGLBundle()),
procName);
CFRelease(procName);
return result;
}
#ifndef QT_MAC_USE_COCOA
/*****************************************************************************
QGLWidget AGL-specific code
*****************************************************************************/
/****************************************************************************
Hacks to glue AGL to an HIView
***************************************************************************/
QRegion qt_mac_get_widget_rgn(const QWidget *widget)
{
if(!widget->isVisible() || widget->isMinimized())
return QRegion();
const QRect wrect = QRect(qt_mac_posInWindow(widget), widget->size());
if(!wrect.isValid())
return QRegion();
RgnHandle macr = qt_mac_get_rgn();
GetControlRegion((HIViewRef)widget->winId(), kControlStructureMetaPart, macr);
OffsetRgn(macr, wrect.x(), wrect.y());
QRegion ret = qt_mac_convert_mac_region(macr);
QPoint clip_pos = wrect.topLeft();
for(const QWidget *last_clip = 0, *clip = widget; clip; last_clip = clip, clip = clip->parentWidget()) {
if(clip != widget) {
GetControlRegion((HIViewRef)clip->winId(), kControlStructureMetaPart, macr);
OffsetRgn(macr, clip_pos.x(), clip_pos.y());
ret &= qt_mac_convert_mac_region(macr);
}
const QObjectList &children = clip->children();
for(int i = children.size()-1; i >= 0; --i) {
if(QWidget *child = qobject_cast<QWidget*>(children.at(i))) {
if(child == last_clip)
break;
// This check may seem weird, but when we are using a unified toolbar
// The widget is actually being owned by that toolbar and not by Qt.
// This means that the geometry it reports will be wrong
// and will accidentally cause problems when calculating the region
// So, it is better to skip these widgets since they aren't the hierarchy
// anyway.
if (HIViewGetSuperview(HIViewRef(child->winId())) != HIViewRef(clip->winId()))
continue;
if(child->isVisible() && !child->isMinimized() && !child->isTopLevel()) {
const QRect childRect = QRect(clip_pos+child->pos(), child->size());
if(childRect.isValid() && wrect.intersects(childRect)) {
GetControlRegion((HIViewRef)child->winId(), kControlStructureMetaPart, macr);
OffsetRgn(macr, childRect.x(), childRect.y());
ret -= qt_mac_convert_mac_region(macr);
}
}
}
}
if(clip->isWindow())
break;
clip_pos -= clip->pos();
}
qt_mac_dispose_rgn(macr);
return ret;
}
#endif
void QGLWidget::setMouseTracking(bool enable)
{
QWidget::setMouseTracking(enable);
}
void QGLWidget::resizeEvent(QResizeEvent *)
{
Q_D(QGLWidget);
if (!isValid())
return;
#ifndef QT_MAC_USE_COCOA
if (!isWindow())
d->glcx->d_func()->update = true;
#endif
makeCurrent();
if (!d->glcx->initialized())
glInit();
#ifdef QT_MAC_USE_COCOA
d->glcx->updatePaintDevice();
#endif
#ifndef QT_MAC_USE_COCOA
float scale = qt_mac_get_scale_factor(this);
resizeGL(width() * scale, height() * scale);
#else
resizeGL(width(), height());
#endif
}
const QGLContext* QGLWidget::overlayContext() const
{
return 0;
}
void QGLWidget::makeOverlayCurrent()
{
}
void QGLWidget::updateOverlayGL()
{
}
void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
{
Q_D(QGLWidget);
if (context == 0) {
qWarning("QGLWidget::setContext: Cannot set null context");
return;
}
if (d->glcx)
d->glcx->doneCurrent();
QGLContext* oldcx = d->glcx;
d->glcx = context;
if (!d->glcx->isValid())
d->glcx->create(shareContext ? shareContext : oldcx);
if (deleteOldContext && oldcx)
delete oldcx;
}
void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
{
Q_Q(QGLWidget);
initContext(context, shareWidget);
QWidget *current = q;
while (current) {
qt_widget_private(current)->glWidgets.append(QWidgetPrivate::GlWidgetInfo(q));
if (current->isWindow())
break;
current = current->parentWidget();
}
}
bool QGLWidgetPrivate::renderCxPm(QPixmap*)
{
return false;
}
void QGLWidgetPrivate::cleanupColormaps()
{
}
const QGLColormap & QGLWidget::colormap() const
{
return d_func()->cmap;
}
void QGLWidget::setColormap(const QGLColormap &)
{
}
void QGLWidgetPrivate::updatePaintDevice()
{
Q_Q(QGLWidget);
glcx->updatePaintDevice();
q->update();
}
#endif
QT_END_NAMESPACE

View File

@ -64,20 +64,13 @@
#include "qcache.h"
#include "qglpaintdevice_p.h"
#ifndef QT_NO_EGL
#include <QtGui/private/qegl_p.h>
#endif
#if defined(Q_WS_QPA)
#include <QtGui/QGuiGLContext>
#endif
QT_BEGIN_NAMESPACE
class QGLContext;
class QGLOverlayWidget;
class QPixmap;
class QPixmapFilter;
#ifdef Q_WS_MAC
# ifdef qDebug
# define old_qDebug qDebug
@ -96,10 +89,6 @@ QT_END_INCLUDE_NAMESPACE
class QMacWindowChangeEvent;
#endif
#ifndef QT_NO_EGL
class QEglContext;
#endif
QT_BEGIN_INCLUDE_NAMESPACE
#include <QtOpenGL/private/qglextensions_p.h>
QT_END_INCLUDE_NAMESPACE
@ -161,15 +150,6 @@ class Q_OPENGL_EXPORT QGLWidgetPrivate : public QWidgetPrivate
public:
QGLWidgetPrivate() : QWidgetPrivate()
, disable_clear_on_painter_begin(false)
#if defined(Q_WS_QWS)
, wsurf(0)
#endif
#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
, eglSurfaceWindowId(0)
#endif
#if defined(Q_OS_SYMBIAN)
, eglSurfaceWindowId(0)
#endif
{
isGLWidget = 1;
}
@ -195,24 +175,6 @@ public:
#endif
bool disable_clear_on_painter_begin;
#if defined(Q_WS_WIN)
void updateColormap();
QGLContext *olcx;
#elif defined(Q_WS_X11)
QGLOverlayWidget *olw;
#ifndef QT_NO_EGL
void recreateEglSurface();
WId eglSurfaceWindowId;
#endif
#elif defined(Q_WS_MAC)
QGLContext *olcx;
void updatePaintDevice();
#endif
#ifdef Q_OS_SYMBIAN
void recreateEglSurface();
WId eglSurfaceWindowId;
#endif
};
class QGLContextGroupResourceBase;
@ -345,54 +307,9 @@ public:
void syncGlState(); // Makes sure the GL context's state is what we think it is
void swapRegion(const QRegion &region);
#if defined(Q_WS_WIN)
void updateFormatVersion();
#endif
#if defined(Q_WS_WIN)
HGLRC rc;
HDC dc;
WId win;
int pixelFormatId;
QGLCmap* cmap;
HBITMAP hbitmap;
HDC hbitmap_hdc;
Qt::HANDLE threadId;
#endif
#ifndef QT_NO_EGL
QEglContext *eglContext;
EGLSurface eglSurface;
void destroyEglSurfaceForDevice();
EGLSurface eglSurfaceForDevice() const;
static QEglProperties *extraWindowSurfaceCreationProps;
static void setExtraWindowSurfaceCreationProps(QEglProperties *props);
#endif
#if defined(Q_WS_QPA)
QGuiGLContext *guiGlContext;
void setupSharing();
#elif defined(Q_WS_X11) || defined(Q_WS_MAC)
void* cx;
#endif
#if defined(Q_WS_X11) || defined(Q_WS_MAC)
void* vi;
#endif
#if defined(Q_WS_X11)
void* pbuf;
quint32 gpm;
int screen;
QHash<QPlatformPixmap*, QPixmap> boundPixmaps;
QGLTexture *bindTextureFromNativePixmap(QPixmap*, const qint64 key,
QGLContext::BindOptions options);
static void destroyGlSurfaceForPixmap(QPlatformPixmap*);
static void unbindPixmapFromTexture(QPlatformPixmap*);
#endif
#if defined(Q_WS_MAC)
bool update;
void *tryFormat(const QGLFormat &format);
void clearDrawable();
#endif
QGLFormat glFormat;
QGLFormat reqFormat;
GLuint fbo;
@ -417,10 +334,6 @@ public:
uint workaround_brokenAlphaTexSubImage : 1;
uint workaround_brokenAlphaTexSubImage_init : 1;
#ifndef QT_NO_EGL
uint ownsEglContext : 1;
#endif
QPaintDevice *paintDevice;
QColor transpColor;
QGLContext *q_ptr;
@ -441,14 +354,8 @@ public:
static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
#ifdef Q_WS_WIN
static inline QGLExtensionFuncs& extensionFuncs(const QGLContext *ctx) { return ctx->d_ptr->group->extensionFuncs(); }
#endif
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
static Q_OPENGL_EXPORT QGLExtensionFuncs qt_extensionFuncs;
static Q_OPENGL_EXPORT QGLExtensionFuncs& extensionFuncs(const QGLContext *);
#endif
static void setCurrentContext(QGLContext *context);
};
@ -514,21 +421,6 @@ Q_SIGNALS:
private slots:
void freeTexture_slot(QGLContext *context, QPlatformPixmap *boundPixmap, GLuint id) {
Q_UNUSED(boundPixmap);
#if defined(Q_WS_X11)
if (boundPixmap) {
QGLContext *oldContext = const_cast<QGLContext *>(QGLContext::currentContext());
context->makeCurrent();
// Although glXReleaseTexImage is a glX call, it must be called while there
// is a current context - the context the pixmap was bound to a texture in.
// Otherwise the release doesn't do anything and you get BadDrawable errors
// when you come to delete the context.
QGLContextPrivate::unbindPixmapFromTexture(boundPixmap);
glDeleteTextures(1, &id);
if (oldContext)
oldContext->makeCurrent();
return;
}
#endif
QGLShareContextScope scope(context);
glDeleteTextures(1, &id);
}
@ -555,17 +447,12 @@ public:
id(tx_id),
target(tx_target),
options(opt)
#if defined(Q_WS_X11)
, boundPixmap(0)
#endif
{}
~QGLTexture() {
if (options & QGLContext::MemoryManagedBindOption) {
Q_ASSERT(context);
#if !defined(Q_WS_X11)
QPlatformPixmap *boundPixmap = 0;
#endif
context->d_ptr->texture_destroyer->emitFreeTexture(context, boundPixmap, id);
}
}
@ -576,10 +463,6 @@ public:
QGLContext::BindOptions options;
#if defined(Q_WS_X11)
QPlatformPixmap* boundPixmap;
#endif
bool canBindCompressedTexture
(const char *buf, int len, const char *format, bool *hasAlpha);
QSize bindCompressedTexture
@ -656,26 +539,6 @@ QGLTexture* QGLTextureCache::getTexture(QGLContext *ctx, qint64 key)
extern Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine();
bool qt_gl_preferGL2Engine();
inline GLenum qt_gl_preferredTextureFormat()
{
return (QGLExtensions::glExtensions() & QGLExtensions::BGRATextureFormat) && QSysInfo::ByteOrder == QSysInfo::LittleEndian
? GL_BGRA : GL_RGBA;
}
inline GLenum qt_gl_preferredTextureTarget()
{
#if defined(QT_OPENGL_ES_2)
return GL_TEXTURE_2D;
#else
return (QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
&& !qt_gl_preferGL2Engine()
? GL_TEXTURE_RECTANGLE_NV
: GL_TEXTURE_2D;
#endif
}
/*
Base for resources that are shared in a context group.
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,636 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qgl.h>
#include <qlist.h>
#include <qmap.h>
#include <qpixmap.h>
#include <qevent.h>
#include <private/qgl_p.h>
#include <qcolormap.h>
#include <qvarlengtharray.h>
#include <qdebug.h>
#include <qapplication.h>
#include <qdesktopwidget>
#include <windows.h>
#include <private/qeglproperties_p.h>
#include <private/qeglcontext_p.h>
#include <private/qgl_egl_p.h>
QT_BEGIN_NAMESPACE
class QGLCmapPrivate
{
public:
QGLCmapPrivate() : count(1) { }
void ref() { ++count; }
bool deref() { return !--count; }
uint count;
enum AllocState{ UnAllocated = 0, Allocated = 0x01, Reserved = 0x02 };
int maxSize;
QVector<uint> colorArray;
QVector<quint8> allocArray;
QVector<quint8> contextArray;
QMap<uint,int> colorMap;
};
/*****************************************************************************
QColorMap class - temporarily here, until it is ready for prime time
*****************************************************************************/
/****************************************************************************
**
** Definition of QColorMap class
**
****************************************************************************/
#ifndef QGLCMAP_H
#define QGLCMAP_H
#include <qcolor.h>
/*
QGLTemporaryContext implementation
*/
class QGLTemporaryContextPrivate
{
public:
QGLWidget *widget;
};
QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
: d(new QGLTemporaryContextPrivate)
{
d->widget = new QGLWidget;
d->widget->makeCurrent();
}
QGLTemporaryContext::~QGLTemporaryContext()
{
delete d->widget;
}
/*****************************************************************************
QGLFormat Win32/WGL-specific code
*****************************************************************************/
static bool opengl32dll = false;
bool QGLFormat::hasOpenGLOverlays()
{
return false; // ###
}
bool QGLContext::chooseContext(const QGLContext* shareContext)
{
Q_D(QGLContext);
// Validate the device.
if (!device())
return false;
int devType = device()->devType();
if (devType != QInternal::Pixmap && devType != QInternal::Image && devType != QInternal::Widget) {
qWarning("QGLContext::chooseContext(): Cannot create QGLContext's for paint device type %d", devType);
return false;
}
// Get the display and initialize it.
d->eglContext = new QEglContext();
d->ownsEglContext = true;
d->eglContext->setApi(QEgl::OpenGL);
// Construct the configuration we need for this surface.
QEglProperties configProps;
qt_eglproperties_set_glformat(configProps, d->glFormat);
configProps.setDeviceType(devType);
configProps.setPaintDeviceFormat(device());
configProps.setRenderableType(QEgl::OpenGL);
// Search for a matching configuration, reducing the complexity
// each time until we get something that matches.
if (!d->eglContext->chooseConfig(configProps)) {
delete d->eglContext;
d->eglContext = 0;
return false;
}
// Inform the higher layers about the actual format properties.
qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
// Create a new context for the configuration.
if (!d->eglContext->createContext
(shareContext ? shareContext->d_func()->eglContext : 0)) {
delete d->eglContext;
d->eglContext = 0;
return false;
}
d->sharing = d->eglContext->isSharing();
if (d->sharing && shareContext)
const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
#if defined(EGL_VERSION_1_1)
if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget)
eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval());
#endif
// Create the EGL surface to draw into.
d->eglSurface = d->eglContext->createSurface(device());
if (d->eglSurface == EGL_NO_SURFACE) {
delete d->eglContext;
d->eglContext = 0;
return false;
}
return true;
}
static bool qLogEq(bool a, bool b)
{
return (((!a) && (!b)) || (a && b));
}
int QGLContext::choosePixelFormat(void* , HDC )
{
return 0;
}
class QGLCmapPrivate;
class /*Q_EXPORT*/ QGLCmap
{
public:
enum Flags { Reserved = 0x01 };
QGLCmap(int maxSize = 256);
QGLCmap(const QGLCmap& map);
~QGLCmap();
QGLCmap& operator=(const QGLCmap& map);
// isEmpty and/or isNull ?
int size() const;
int maxSize() const;
void resize(int newSize);
int find(QRgb color) const;
int findNearest(QRgb color) const;
int allocate(QRgb color, uint flags = 0, quint8 context = 0);
void setEntry(int idx, QRgb color, uint flags = 0, quint8 context = 0);
const QRgb* colors() const;
private:
void detach();
QGLCmapPrivate* d;
};
#endif
QGLCmap::QGLCmap(int maxSize) // add a bool prealloc?
{
d = new QGLCmapPrivate;
d->maxSize = maxSize;
}
QGLCmap::QGLCmap(const QGLCmap& map)
{
d = map.d;
d->ref();
}
QGLCmap::~QGLCmap()
{
if (d && d->deref())
delete d;
d = 0;
}
QGLCmap& QGLCmap::operator=(const QGLCmap& map)
{
map.d->ref();
if (d->deref())
delete d;
d = map.d;
return *this;
}
int QGLCmap::size() const
{
return d->colorArray.size();
}
int QGLCmap::maxSize() const
{
return d->maxSize;
}
void QGLCmap::detach()
{
if (d->count != 1) {
d->deref();
QGLCmapPrivate* newd = new QGLCmapPrivate;
newd->maxSize = d->maxSize;
newd->colorArray = d->colorArray;
newd->allocArray = d->allocArray;
newd->contextArray = d->contextArray;
newd->colorArray.detach();
newd->allocArray.detach();
newd->contextArray.detach();
newd->colorMap = d->colorMap;
d = newd;
}
}
void QGLCmap::resize(int newSize)
{
if (newSize < 0 || newSize > d->maxSize) {
qWarning("QGLCmap::resize(): size out of range");
return;
}
int oldSize = size();
detach();
//if shrinking; remove the lost elems from colorMap
d->colorArray.resize(newSize);
d->allocArray.resize(newSize);
d->contextArray.resize(newSize);
if (newSize > oldSize) {
memset(d->allocArray.data() + oldSize, 0, newSize - oldSize);
memset(d->contextArray.data() + oldSize, 0, newSize - oldSize);
}
}
int QGLCmap::find(QRgb color) const
{
QMap<uint,int>::ConstIterator it = d->colorMap.find(color);
if (it != d->colorMap.end())
return *it;
return -1;
}
int QGLCmap::findNearest(QRgb color) const
{
int idx = find(color);
if (idx >= 0)
return idx;
int mapSize = size();
int mindist = 200000;
int r = qRed(color);
int g = qGreen(color);
int b = qBlue(color);
int rx, gx, bx, dist;
for (int i=0; i < mapSize; i++) {
if (!(d->allocArray[i] & QGLCmapPrivate::Allocated))
continue;
QRgb ci = d->colorArray[i];
rx = r - qRed(ci);
gx = g - qGreen(ci);
bx = b - qBlue(ci);
dist = rx*rx + gx*gx + bx*bx; // calculate distance
if (dist < mindist) { // minimal?
mindist = dist;
idx = i;
}
}
return idx;
}
// Does not always allocate; returns existing c idx if found
int QGLCmap::allocate(QRgb color, uint flags, quint8 context)
{
int idx = find(color);
if (idx >= 0)
return idx;
int mapSize = d->colorArray.size();
int newIdx = d->allocArray.indexOf(QGLCmapPrivate::UnAllocated);
if (newIdx < 0) { // Must allocate more room
if (mapSize < d->maxSize) {
newIdx = mapSize;
mapSize++;
resize(mapSize);
}
else {
//# add a bool param that says what to do in case no more room -
// fail (-1) or return nearest?
return -1;
}
}
d->colorArray[newIdx] = color;
if (flags & QGLCmap::Reserved) {
d->allocArray[newIdx] = QGLCmapPrivate::Reserved;
}
else {
d->allocArray[newIdx] = QGLCmapPrivate::Allocated;
d->colorMap.insert(color, newIdx);
}
d->contextArray[newIdx] = context;
return newIdx;
}
void QGLCmap::setEntry(int idx, QRgb color, uint flags, quint8 context)
{
if (idx < 0 || idx >= d->maxSize) {
qWarning("QGLCmap::set(): Index out of range");
return;
}
detach();
int mapSize = size();
if (idx >= mapSize) {
mapSize = idx + 1;
resize(mapSize);
}
d->colorArray[idx] = color;
if (flags & QGLCmap::Reserved) {
d->allocArray[idx] = QGLCmapPrivate::Reserved;
}
else {
d->allocArray[idx] = QGLCmapPrivate::Allocated;
d->colorMap.insert(color, idx);
}
d->contextArray[idx] = context;
}
const QRgb* QGLCmap::colors() const
{
return d->colorArray.data();
}
/*****************************************************************************
QGLWidget Win32/WGL-specific code
*****************************************************************************/
void QGLWidgetPrivate::init(QGLContext *ctx, const QGLWidget* shareWidget)
{
Q_Q(QGLWidget);
olcx = 0;
initContext(ctx, shareWidget);
if (q->isValid() && q->context()->format().hasOverlay()) {
olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), q);
if (!olcx->create(shareWidget ? shareWidget->overlayContext() : 0)) {
delete olcx;
olcx = 0;
glcx->d_func()->glFormat.setOverlay(false);
}
} else {
olcx = 0;
}
}
/*\internal
Store color values in the given colormap.
*/
static void qStoreColors(HPALETTE cmap, const QGLColormap & cols)
{
QRgb color;
PALETTEENTRY pe;
for (int i = 0; i < cols.size(); i++) {
color = cols.entryRgb(i);
pe.peRed = qRed(color);
pe.peGreen = qGreen(color);
pe.peBlue = qBlue(color);
pe.peFlags = 0;
SetPaletteEntries(cmap, i, 1, &pe);
}
}
void QGLWidgetPrivate::updateColormap()
{
Q_Q(QGLWidget);
if (!cmap.handle())
return;
HDC hdc = GetDC(q->winId());
SelectPalette(hdc, (HPALETTE) cmap.handle(), TRUE);
qStoreColors((HPALETTE) cmap.handle(), cmap);
RealizePalette(hdc);
ReleaseDC(q->winId(), hdc);
}
bool QGLWidget::event(QEvent *e)
{
Q_D(QGLWidget);
if (e->type() == QEvent::ParentChange) {
setContext(new QGLContext(d->glcx->requestedFormat(), this));
// the overlay needs to be recreated as well
delete d->olcx;
if (isValid() && context()->format().hasOverlay()) {
d->olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), this);
if (!d->olcx->create(isSharing() ? d->glcx : 0)) {
delete d->olcx;
d->olcx = 0;
d->glcx->d_func()->glFormat.setOverlay(false);
}
} else {
d->olcx = 0;
}
} else if (e->type() == QEvent::Show && !format().rgba()) {
d->updateColormap();
}
return QWidget::event(e);
}
void QGLWidget::resizeEvent(QResizeEvent *)
{
Q_D(QGLWidget);
if (!isValid())
return;
makeCurrent();
if (!d->glcx->initialized())
glInit();
resizeGL(width(), height());
if (d->olcx) {
makeOverlayCurrent();
resizeOverlayGL(width(), height());
}
}
const QGLContext* QGLWidget::overlayContext() const
{
return d_func()->olcx;
}
void QGLWidget::makeOverlayCurrent()
{
Q_D(QGLWidget);
if (d->olcx) {
d->olcx->makeCurrent();
if (!d->olcx->initialized()) {
initializeOverlayGL();
d->olcx->setInitialized(true);
}
}
}
void QGLWidget::updateOverlayGL()
{
Q_D(QGLWidget);
if (d->olcx) {
makeOverlayCurrent();
paintOverlayGL();
if (d->olcx->format().doubleBuffer()) {
if (d->autoSwap)
d->olcx->swapBuffers();
}
else {
glFlush();
}
}
}
void QGLWidget::setContext(QGLContext *context,
const QGLContext* shareContext,
bool deleteOldContext)
{
Q_D(QGLWidget);
if (context == 0) {
qWarning("QGLWidget::setContext: Cannot set null context");
return;
}
if (!context->deviceIsPixmap() && context->device() != this) {
qWarning("QGLWidget::setContext: Context must refer to this widget");
return;
}
if (d->glcx)
d->glcx->doneCurrent();
QGLContext* oldcx = d->glcx;
d->glcx = context;
bool doShow = false;
if (oldcx && oldcx->d_func()->win == winId() && !d->glcx->deviceIsPixmap()) {
// We already have a context and must therefore create a new
// window since Windows does not permit setting a new OpenGL
// context for a window that already has one set.
doShow = isVisible();
QWidget *pW = static_cast<QWidget *>(parent());
QPoint pos = geometry().topLeft();
setParent(pW, windowFlags());
move(pos);
}
if (!d->glcx->isValid()) {
d->glcx->create(shareContext ? shareContext : oldcx);
// the above is a trick to keep disp lists etc when a
// QGLWidget has been reparented, so remove the sharing
// flag if we don't actually have a sharing context.
if (!shareContext)
d->glcx->d_ptr->sharing = false;
}
if (deleteOldContext)
delete oldcx;
if (doShow)
show();
}
void QGLWidgetPrivate::cleanupColormaps()
{
Q_Q(QGLWidget);
if (cmap.handle()) {
HDC hdc = GetDC(q->winId());
SelectPalette(hdc, (HPALETTE) GetStockObject(DEFAULT_PALETTE), FALSE);
DeleteObject((HPALETTE) cmap.handle());
ReleaseDC(q->winId(), hdc);
cmap.setHandle(0);
}
return;
}
const QGLColormap & QGLWidget::colormap() const
{
return d_func()->cmap;
}
void QGLWidget::setColormap(const QGLColormap & c)
{
Q_D(QGLWidget);
d->cmap = c;
if (d->cmap.handle()) { // already have an allocated cmap
d->updateColormap();
} else {
LOGPALETTE *lpal = (LOGPALETTE *) malloc(sizeof(LOGPALETTE)
+c.size()*sizeof(PALETTEENTRY));
lpal->palVersion = 0x300;
lpal->palNumEntries = c.size();
d->cmap.setHandle(CreatePalette(lpal));
free(lpal);
d->updateColormap();
}
}
QT_END_NAMESPACE

File diff suppressed because it is too large Load Diff

View File

@ -1,548 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qgl.h"
#include <private/qt_x11_p.h>
#include <private/qpixmap_x11_p.h>
#include <private/qgl_p.h>
#include <private/qpaintengine_opengl_p.h>
#include "qgl_egl_p.h"
#include "qcolormap.h"
#include <QDebug>
#include <QPixmap>
QT_BEGIN_NAMESPACE
/*
QGLTemporaryContext implementation
*/
class QGLTemporaryContextPrivate
{
public:
bool initialized;
Window window;
EGLContext context;
EGLSurface surface;
EGLDisplay display;
};
QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
: d(new QGLTemporaryContextPrivate)
{
d->initialized = false;
d->window = 0;
d->context = 0;
d->surface = 0;
int screen = 0;
d->display = QEgl::display();
EGLConfig config;
int numConfigs = 0;
EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
#ifdef QT_OPENGL_ES_2
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#endif
EGL_NONE
};
eglChooseConfig(d->display, attribs, &config, 1, &numConfigs);
if (!numConfigs) {
qWarning("QGLTemporaryContext: No EGL configurations available.");
return;
}
XVisualInfo visualInfo;
XVisualInfo *vi;
int numVisuals;
visualInfo.visualid = QEgl::getCompatibleVisualId(config);
vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals);
if (!vi || numVisuals < 1) {
qWarning("QGLTemporaryContext: Unable to get X11 visual info id.");
return;
}
XSetWindowAttributes attr;
unsigned long mask;
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap(X11->display, DefaultRootWindow(X11->display), vi->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
d->window = XCreateWindow(X11->display, RootWindow(X11->display, screen),
0, 0, 1, 1, 0,
vi->depth, InputOutput, vi->visual,
mask, &attr);
d->surface = eglCreateWindowSurface(d->display, config, (EGLNativeWindowType) d->window, NULL);
if (d->surface == EGL_NO_SURFACE) {
qWarning("QGLTemporaryContext: Error creating EGL surface.");
XFree(vi);
XDestroyWindow(X11->display, d->window);
return;
}
EGLint contextAttribs[] = {
#ifdef QT_OPENGL_ES_2
EGL_CONTEXT_CLIENT_VERSION, 2,
#endif
EGL_NONE
};
d->context = eglCreateContext(d->display, config, 0, contextAttribs);
if (d->context != EGL_NO_CONTEXT
&& eglMakeCurrent(d->display, d->surface, d->surface, d->context))
{
d->initialized = true;
} else {
qWarning("QGLTemporaryContext: Error creating EGL context.");
eglDestroySurface(d->display, d->surface);
XDestroyWindow(X11->display, d->window);
}
XFree(vi);
}
QGLTemporaryContext::~QGLTemporaryContext()
{
if (d->initialized) {
eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(d->display, d->context);
eglDestroySurface(d->display, d->surface);
XDestroyWindow(X11->display, d->window);
}
}
bool QGLFormat::hasOpenGLOverlays()
{
return false;
}
// Chooses the EGL config and creates the EGL context
bool QGLContext::chooseContext(const QGLContext* shareContext)
{
Q_D(QGLContext);
if (!device())
return false;
int devType = device()->devType();
QX11PlatformPixmap *x11PlatformPixmap = 0;
if (devType == QInternal::Pixmap) {
QPlatformPixmap *pmd = static_cast<QPixmap*>(device())->data_ptr().data();
if (pmd->classId() == QPlatformPixmap::X11Class)
x11PlatformPixmap = static_cast<QX11PlatformPixmap*>(pmd);
else {
// TODO: Replace the pixmap's data with a new QX11PlatformPixmap
qWarning("WARNING: Creating a QGLContext on a QPixmap is only supported for X11 pixmap backend");
return false;
}
} else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) {
qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType);
return false;
}
// Only create the eglContext if we don't already have one:
if (d->eglContext == 0) {
d->eglContext = new QEglContext();
d->ownsEglContext = true;
d->eglContext->setApi(QEgl::OpenGL);
// If the device is a widget with WA_TranslucentBackground set, make sure the glFormat
// has the alpha channel option set:
if (devType == QInternal::Widget) {
QWidget* widget = static_cast<QWidget*>(device());
if (widget->testAttribute(Qt::WA_TranslucentBackground))
d->glFormat.setAlpha(true);
}
// Construct the configuration we need for this surface.
QEglProperties configProps;
configProps.setDeviceType(devType);
configProps.setRenderableType(QEgl::OpenGL);
qt_eglproperties_set_glformat(configProps, d->glFormat);
// Set buffer preserved for regular QWidgets, QGLWidgets are ok with either preserved or destroyed:
if ((devType == QInternal::Widget) && qobject_cast<QGLWidget*>(static_cast<QWidget*>(device())) == 0)
configProps.setValue(EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) {
delete d->eglContext;
d->eglContext = 0;
return false;
}
// Create a new context for the configuration.
QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0;
if (!d->eglContext->createContext(eglSharedContext)) {
delete d->eglContext;
d->eglContext = 0;
return false;
}
d->sharing = d->eglContext->isSharing();
if (d->sharing && shareContext)
const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
}
// Inform the higher layers about the actual format properties
qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
// Do don't create the EGLSurface for everything.
// QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
// QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
// QPixmap - yes, create the EGLSurface but store it in QX11PlatformPixmap::gl_surface
// QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf
if (devType == QInternal::Widget) {
if (d->eglSurface != EGL_NO_SURFACE)
eglDestroySurface(d->eglContext->display(), d->eglSurface);
// extraWindowSurfaceCreationProps default to NULL unless were specifically set before
d->eglSurface = QEgl::createSurface(device(), d->eglContext->config(), d->extraWindowSurfaceCreationProps);
XFlush(X11->display);
setWindowCreated(true);
}
if (x11PlatformPixmap) {
// TODO: Actually check to see if the existing surface can be re-used
if (x11PlatformPixmap->gl_surface)
eglDestroySurface(d->eglContext->display(), (EGLSurface)x11PlatformPixmap->gl_surface);
x11PlatformPixmap->gl_surface = (void*)QEgl::createSurface(device(), d->eglContext->config());
}
return true;
}
void QGLWidget::resizeEvent(QResizeEvent *)
{
Q_D(QGLWidget);
if (!isValid())
return;
makeCurrent();
if (!d->glcx->initialized())
glInit();
resizeGL(width(), height());
//handle overlay
}
const QGLContext* QGLWidget::overlayContext() const
{
return 0;
}
void QGLWidget::makeOverlayCurrent()
{
//handle overlay
}
void QGLWidget::updateOverlayGL()
{
//handle overlay
}
void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
{
Q_D(QGLWidget);
if (context == 0) {
qWarning("QGLWidget::setContext: Cannot set null context");
return;
}
if (!context->deviceIsPixmap() && context->device() != this) {
qWarning("QGLWidget::setContext: Context must refer to this widget");
return;
}
if (d->glcx)
d->glcx->doneCurrent();
QGLContext* oldcx = d->glcx;
d->glcx = context;
bool createFailed = false;
if (!d->glcx->isValid()) {
// Create the QGLContext here, which in turn chooses the EGL config
// and creates the EGL context:
if (!d->glcx->create(shareContext ? shareContext : oldcx))
createFailed = true;
}
if (createFailed) {
if (deleteOldContext)
delete oldcx;
return;
}
d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for
}
void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
{
Q_Q(QGLWidget);
initContext(context, shareWidget);
if (q->isValid() && glcx->format().hasOverlay()) {
//no overlay
qWarning("QtOpenGL ES doesn't currently support overlays");
}
}
void QGLWidgetPrivate::cleanupColormaps()
{
}
const QGLColormap & QGLWidget::colormap() const
{
return d_func()->cmap;
}
void QGLWidget::setColormap(const QGLColormap &)
{
}
// Re-creates the EGL surface if the window ID has changed or if there isn't a surface
void QGLWidgetPrivate::recreateEglSurface()
{
Q_Q(QGLWidget);
Window currentId = q->winId();
// If the window ID has changed since the surface was created, we need to delete the
// old surface before re-creating a new one. Note: This should not be the case as the
// surface should be deleted before the old window id.
if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) {
qWarning("EGL surface for deleted window %lx was not destroyed", uint(eglSurfaceWindowId));
glcx->d_func()->destroyEglSurfaceForDevice();
}
if (glcx->d_func()->eglSurface == EGL_NO_SURFACE) {
glcx->d_func()->eglSurface = glcx->d_func()->eglContext->createSurface(q);
eglSurfaceWindowId = currentId;
}
}
QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key,
QGLContext::BindOptions options)
{
Q_Q(QGLContext);
// The EGL texture_from_pixmap has no facility to invert the y coordinate
if (!(options & QGLContext::CanFlipNativePixmapBindOption))
return 0;
static bool checkedForTFP = false;
static bool haveTFP = false;
static bool checkedForEglImageTFP = false;
static bool haveEglImageTFP = false;
if (!checkedForEglImageTFP) {
checkedForEglImageTFP = true;
// We need to be able to create an EGLImage from a native pixmap, which was split
// into a separate EGL extension, EGL_KHR_image_pixmap. It is possible to have
// eglCreateImageKHR & eglDestroyImageKHR without support for pixmaps, so we must
// check we have the EGLImage from pixmap functionality.
if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) {
// Being able to create an EGLImage from a native pixmap is also pretty useless
// without the ability to bind that EGLImage as a texture, which is provided by
// the GL_OES_EGL_image extension, which we try to resolve here:
haveEglImageTFP = qt_resolve_eglimage_gl_extensions(q);
if (haveEglImageTFP)
qDebug("Found EGL_KHR_image_pixmap & GL_OES_EGL_image extensions (preferred method)!");
}
}
if (!checkedForTFP) {
// Check for texture_from_pixmap egl extension
checkedForTFP = true;
if (QEgl::hasExtension("EGL_NOKIA_texture_from_pixmap") ||
QEgl::hasExtension("EGL_EXT_texture_from_pixmap"))
{
qDebug("Found texture_from_pixmap EGL extension!");
haveTFP = true;
}
}
if (!haveTFP && !haveEglImageTFP)
return 0;
QX11PlatformPixmap *handle = static_cast<QX11PlatformPixmap*>(pixmap->data_ptr().data());
Q_ASSERT(handle->classId() == QPlatformPixmap::X11Class);
bool hasAlpha = handle->hasAlphaChannel();
bool pixmapHasValidSurface = false;
bool textureIsBound = false;
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
if (haveTFP && handle->gl_surface &&
hasAlpha == (handle->flags & QX11PlatformPixmap::GlSurfaceCreatedWithAlpha))
{
pixmapHasValidSurface = true;
}
// If we already have a valid EGL surface for the pixmap, we should use it
if (pixmapHasValidSurface) {
EGLBoolean success;
success = eglBindTexImage(QEgl::display(), (EGLSurface)handle->gl_surface, EGL_BACK_BUFFER);
if (success == EGL_FALSE) {
qWarning() << "eglBindTexImage() failed:" << QEgl::errorString();
eglDestroySurface(QEgl::display(), (EGLSurface)handle->gl_surface);
handle->gl_surface = (void*)EGL_NO_SURFACE;
} else
textureIsBound = true;
}
// If the pixmap doesn't already have a valid surface, try binding it via EGLImage
// first, as going through EGLImage should be faster and better supported:
if (!textureIsBound && haveEglImageTFP) {
EGLImageKHR eglImage;
EGLint attribs[] = {
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
EGL_NONE
};
eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
(EGLClientBuffer)QEgl::nativePixmap(pixmap), attribs);
QGLContext* ctx = q;
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);
GLint err = glGetError();
if (err == GL_NO_ERROR)
textureIsBound = true;
// Once the egl image is bound, the texture becomes a new sibling image and we can safely
// destroy the EGLImage we created for the pixmap:
if (eglImage != EGL_NO_IMAGE_KHR)
QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
}
if (!textureIsBound && haveTFP) {
// Check to see if the surface is still valid
if (handle->gl_surface &&
hasAlpha != (handle->flags & QX11PlatformPixmap::GlSurfaceCreatedWithAlpha))
{
// Surface is invalid!
destroyGlSurfaceForPixmap(handle);
}
if (handle->gl_surface == 0) {
EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap,
QEgl::OpenGL,
hasAlpha ? QEgl::Translucent : QEgl::NoOptions);
handle->gl_surface = (void*)QEgl::createSurface(pixmap, config);
if (handle->gl_surface == (void*)EGL_NO_SURFACE)
return false;
}
EGLBoolean success;
success = eglBindTexImage(QEgl::display(), (EGLSurface)handle->gl_surface, EGL_BACK_BUFFER);
if (success == EGL_FALSE) {
qWarning() << "eglBindTexImage() failed:" << QEgl::errorString();
eglDestroySurface(QEgl::display(), (EGLSurface)handle->gl_surface);
handle->gl_surface = (void*)EGL_NO_SURFACE;
haveTFP = false; // If TFP isn't working, disable it's use
} else
textureIsBound = true;
}
QGLTexture *texture = 0;
if (textureIsBound) {
texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options);
handle->flags |= QX11PlatformPixmap::InvertedWhenBoundToTexture;
// We assume the cost of bound pixmaps is zero
QGLTextureCache::instance()->insert(q, key, texture, 0);
glBindTexture(GL_TEXTURE_2D, textureId);
} else
glDeleteTextures(1, &textureId);
return texture;
}
void QGLContextPrivate::destroyGlSurfaceForPixmap(QPlatformPixmap* pmd)
{
Q_ASSERT(pmd->classId() == QPlatformPixmap::X11Class);
QX11PlatformPixmap *handle = static_cast<QX11PlatformPixmap*>(pmd);
if (handle->gl_surface) {
EGLBoolean success;
success = eglDestroySurface(QEgl::display(), (EGLSurface)handle->gl_surface);
if (success == EGL_FALSE) {
qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: "
<< QEgl::errorString();
}
handle->gl_surface = 0;
}
}
void QGLContextPrivate::unbindPixmapFromTexture(QPlatformPixmap* pmd)
{
Q_ASSERT(pmd->classId() == QPlatformPixmap::X11Class);
QX11PlatformPixmap *handle = static_cast<QX11PlatformPixmap*>(pmd);
if (handle->gl_surface) {
EGLBoolean success;
success = eglReleaseTexImage(QEgl::display(),
(EGLSurface)handle->gl_surface,
EGL_BACK_BUFFER);
if (success == EGL_FALSE) {
qWarning() << "unbindPixmapFromTexture() - Unable to release bound texture: "
<< QEgl::errorString();
}
}
}
QT_END_NAMESPACE

View File

@ -245,17 +245,7 @@ QGLBuffer::UsagePattern QGLBuffer::usagePattern() const
void QGLBuffer::setUsagePattern(QGLBuffer::UsagePattern value)
{
Q_D(QGLBuffer);
#if defined(QT_OPENGL_ES_1)
// OpenGL/ES 1.1 does not support GL_STREAM_DRAW, so use GL_STATIC_DRAW.
// OpenGL/ES 2.0 does support GL_STREAM_DRAW.
d->usagePattern = value;
if (value == StreamDraw)
d->actualUsagePattern = StaticDraw;
else
d->actualUsagePattern = value;
#else
d->usagePattern = d->actualUsagePattern = value;
#endif
}
#undef ctx

View File

@ -222,17 +222,6 @@ bool qt_resolve_buffer_extensions(QGLContext *ctx)
#endif
}
#ifndef QT_NO_EGL
bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx)
{
if (glEGLImageTargetTexture2DOES || glEGLImageTargetRenderbufferStorageOES)
return true;
glEGLImageTargetTexture2DOES = (_glEGLImageTargetTexture2DOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetTexture2DOES"));
glEGLImageTargetRenderbufferStorageOES = (_glEGLImageTargetRenderbufferStorageOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetRenderbufferStorageOES"));
return glEGLImageTargetTexture2DOES && glEGLImageTargetRenderbufferStorageOES;
}
#endif
bool qt_resolve_glsl_extensions(QGLContext *ctx)
{

View File

@ -68,11 +68,6 @@
# define APIENTRYP *
#endif
#ifndef QT_NO_EGL
// Needed for EGLImageKHR definition:
#include <QtGui/private/qegl_p.h>
#endif
#include <QtCore/qglobal.h>
#ifndef GL_ARB_vertex_buffer_object
@ -214,15 +209,6 @@ typedef void (APIENTRY *_glFramebufferTextureFaceEXT)(GLenum target, GLenum atta
// ARB_texture_compression
typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
GLsizei, GLint, GLsizei, const GLvoid *);
#ifndef QT_NO_EGL
// OES_EGL_image
// Note: We define these to take EGLImage whereas spec says they take a new GLeglImageOES
// type, which the EGL image should be cast to.
typedef void (APIENTRY *_glEGLImageTargetTexture2DOES) (GLenum, EGLImageKHR);
typedef void (APIENTRY *_glEGLImageTargetRenderbufferStorageOES) (GLenum, EGLImageKHR);
#endif
QT_BEGIN_NAMESPACE
struct QGLExtensionFuncs
@ -340,12 +326,6 @@ struct QGLExtensionFuncs
// Texture compression
qt_glCompressedTexImage2DARB = 0;
#endif
#ifndef QT_NO_EGL
// OES_EGL_image
qt_glEGLImageTargetTexture2DOES = 0;
qt_glEGLImageTargetRenderbufferStorageOES = 0;
#endif
}
@ -466,12 +446,6 @@ struct QGLExtensionFuncs
// Texture compression
_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB;
#endif
#ifndef QT_NO_EGL
// OES_EGL_image
_glEGLImageTargetTexture2DOES qt_glEGLImageTargetTexture2DOES;
_glEGLImageTargetRenderbufferStorageOES qt_glEGLImageTargetRenderbufferStorageOES;
#endif
};
@ -880,12 +854,6 @@ struct QGLExtensionFuncs
#define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB
#endif
#ifndef QT_NO_EGL
// OES_EGL_image
#define glEGLImageTargetTexture2DOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetTexture2DOES
#define glEGLImageTargetRenderbufferStorageOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetRenderbufferStorageOES
#endif
extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx);
bool Q_OPENGL_EXPORT qt_resolve_buffer_extensions(QGLContext *ctx);
@ -896,10 +864,6 @@ bool qt_resolve_frag_program_extensions(QGLContext *ctx);
bool qt_resolve_glsl_extensions(QGLContext *ctx);
#ifndef QT_NO_EGL
Q_OPENGL_EXPORT bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx);
#endif
QT_END_NAMESPACE
#endif // QGL_EXTENSIONS_P_H

View File

@ -45,13 +45,7 @@
#include <qdebug.h>
#include <private/qgl_p.h>
#include <private/qfont_p.h>
#if !defined(QT_OPENGL_ES_1)
#include <private/qpaintengineex_opengl2_p.h>
#endif
#ifndef QT_OPENGL_ES_2
#include <private/qpaintengine_opengl_p.h>
#endif
#include <qglframebufferobject.h>
#include <qlibrary.h>
@ -306,22 +300,6 @@ GLenum QGLFramebufferObjectFormat::internalTextureFormat() const
return d->internal_format;
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLFramebufferObjectFormat::setTextureTarget(QMacCompatGLenum target)
{
detach();
d->target = target;
}
/*! \internal */
void QGLFramebufferObjectFormat::setInternalTextureFormat(QMacCompatGLenum internalTextureFormat)
{
detach();
d->internal_format = internalTextureFormat;
}
#endif
/*!
Returns true if all the options of this framebuffer object format
are the same as \a other; otherwise returns false.
@ -720,8 +698,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
As of Qt 4.8, it's possible to draw into a QGLFramebufferObject
using a QPainter in a separate thread. Note that OpenGL 2.0 or
OpenGL ES 2.0 is required for this to work. Also, under X11, it's
necessary to set the Qt::AA_X11InitThreads application attribute.
OpenGL ES 2.0 is required for this to work.
\sa {Framebuffer Object Example}
*/
@ -780,16 +757,6 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)
d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
QGLFramebufferObject::QGLFramebufferObject(const QSize &size, QMacCompatGLenum target)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
}
#endif
/*! \overload
Constructs an OpenGL framebuffer object and binds a 2D GL texture
@ -832,16 +799,6 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, const QGLFrame
format.internalTextureFormat(), format.samples(), format.mipmap());
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
QGLFramebufferObject::QGLFramebufferObject(int width, int height, QMacCompatGLenum target)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
}
#endif
/*! \overload
Constructs an OpenGL framebuffer object and binds a texture to the
@ -863,17 +820,6 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att
d->init(this, QSize(width, height), attachment, target, internal_format);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment attachment,
QMacCompatGLenum target, QMacCompatGLenum internal_format)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
d->init(this, QSize(width, height), attachment, target, internal_format);
}
#endif
/*! \overload
Constructs an OpenGL framebuffer object and binds a texture to the
@ -895,17 +841,6 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
d->init(this, size, attachment, target, internal_format);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachment,
QMacCompatGLenum target, QMacCompatGLenum internal_format)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
d->init(this, size, attachment, target, internal_format);
}
#endif
/*!
\fn QGLFramebufferObject::~QGLFramebufferObject()
@ -1092,13 +1027,7 @@ QImage QGLFramebufferObject::toImage() const
return image;
}
#if !defined(QT_OPENGL_ES_1)
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)
#endif
#ifndef QT_OPENGL_ES_2
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_buffer_engine)
#endif
/*! \reimp */
QPaintEngine *QGLFramebufferObject::paintEngine() const
@ -1107,29 +1036,12 @@ QPaintEngine *QGLFramebufferObject::paintEngine() const
if (d->engine)
return d->engine;
#if !defined(QT_OPENGL_ES_1)
#if !defined (QT_OPENGL_ES_2)
if (qt_gl_preferGL2Engine()) {
#endif
QPaintEngine *engine = qt_buffer_2_engine()->engine();
if (engine->isActive() && engine->paintDevice() != this) {
d->engine = new QGL2PaintEngineEx;
return d->engine;
}
return engine;
#if !defined (QT_OPENGL_ES_2)
}
#endif
#endif
#if !defined(QT_OPENGL_ES_2)
QPaintEngine *engine = qt_buffer_engine()->engine();
QPaintEngine *engine = qt_buffer_2_engine()->engine();
if (engine->isActive() && engine->paintDevice() != this) {
d->engine = new QOpenGLPaintEngine;
d->engine = new QGL2PaintEngineEx;
return d->engine;
}
return engine;
#endif
}
/*!
@ -1189,14 +1101,6 @@ void QGLFramebufferObject::drawTexture(const QRectF &target, GLuint textureId, G
const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLFramebufferObject::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
}
#endif
/*!
\since 4.4
@ -1212,14 +1116,6 @@ void QGLFramebufferObject::drawTexture(const QPointF &point, GLuint textureId, G
const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLFramebufferObject::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
}
#endif
/*! \reimp */
int QGLFramebufferObject::metric(PaintDeviceMetric metric) const
{

View File

@ -81,16 +81,6 @@ public:
QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format);
QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format);
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
QGLFramebufferObject(const QSize &size, QMacCompatGLenum target = GL_TEXTURE_2D);
QGLFramebufferObject(int width, int height, QMacCompatGLenum target = GL_TEXTURE_2D);
QGLFramebufferObject(const QSize &size, Attachment attachment,
QMacCompatGLenum target = GL_TEXTURE_2D, QMacCompatGLenum internal_format = GL_RGBA8);
QGLFramebufferObject(int width, int height, Attachment attachment,
QMacCompatGLenum target = GL_TEXTURE_2D, QMacCompatGLenum internal_format = GL_RGBA8);
#endif
virtual ~QGLFramebufferObject();
QGLFramebufferObjectFormat format() const;
@ -114,10 +104,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
#endif
static bool hasOpenGLFramebufferBlit();
static void blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect,
@ -160,11 +146,6 @@ public:
void setInternalTextureFormat(GLenum internalTextureFormat);
GLenum internalTextureFormat() const;
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
void setTextureTarget(QMacCompatGLenum target);
void setInternalTextureFormat(QMacCompatGLenum internalTextureFormat);
#endif
bool operator==(const QGLFramebufferObjectFormat& other) const;
bool operator!=(const QGLFramebufferObjectFormat& other) const;

View File

@ -419,7 +419,7 @@ struct QGLFunctionsPrivate
inline void QGLFunctions::glActiveTexture(GLenum texture)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
::glActiveTexture(texture);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@ -449,7 +449,7 @@ inline void QGLFunctions::glBindAttribLocation(GLuint program, GLuint index, con
inline void QGLFunctions::glBindBuffer(GLenum target, GLuint buffer)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
::glBindBuffer(target, buffer);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@ -519,7 +519,7 @@ inline void QGLFunctions::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLen
inline void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
::glBufferData(target, size, data, usage);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@ -529,7 +529,7 @@ inline void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const
inline void QGLFunctions::glBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
::glBufferSubData(target, offset, size, data);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@ -568,7 +568,7 @@ inline void QGLFunctions::glCompileShader(GLuint shader)
inline void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
::glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@ -578,7 +578,7 @@ inline void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLe
inline void QGLFunctions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
::glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@ -608,7 +608,7 @@ inline GLuint QGLFunctions::glCreateShader(GLenum type)
inline void QGLFunctions::glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
::glDeleteBuffers(n, buffers);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@ -717,7 +717,7 @@ inline void QGLFunctions::glFramebufferTexture2D(GLenum target, GLenum attachmen
inline void QGLFunctions::glGenBuffers(GLsizei n, GLuint* buffers)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
::glGenBuffers(n, buffers);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@ -947,7 +947,7 @@ inline void QGLFunctions::glGetVertexAttribPointerv(GLuint index, GLenum pname,
inline GLboolean QGLFunctions::glIsBuffer(GLuint buffer)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
return ::glIsBuffer(buffer);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@ -1027,7 +1027,7 @@ inline void QGLFunctions::glRenderbufferStorage(GLenum target, GLenum internalfo
inline void QGLFunctions::glSampleCoverage(GLclampf value, GLboolean invert)
{
#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
#if defined(QT_OPENGL_ES_2)
::glSampleCoverage(value, invert);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));

View File

@ -81,8 +81,7 @@
As of Qt 4.8, it's possible to render into a QGLPixelBuffer using
a QPainter in a separate thread. Note that OpenGL 2.0 or OpenGL ES
2.0 is required for this to work. Also, under X11, it's necessary
to set the Qt::AA_X11InitThreads application attribute.
2.0 is required for this to work.
Pbuffers are provided by the OpenGL \c pbuffer extension; call
hasOpenGLPbuffer() to find out if the system provides pbuffers.
@ -92,19 +91,13 @@
#include <QtCore/qglobal.h>
#if !defined(QT_OPENGL_ES_1)
#include <private/qpaintengineex_opengl2_p.h>
#endif
#include <qglpixelbuffer.h>
#include <private/qglpixelbuffer_p.h>
#include <private/qfont_p.h>
#include <qimage.h>
#ifndef QT_OPENGL_ES_2
#include <private/qpaintengine_opengl_p.h>
#endif
QT_BEGIN_NAMESPACE
#if !defined(QT_OPENGL_ES_2)
@ -149,20 +142,6 @@ void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &form
glDevice.setPBuffer(q);
qctx->d_func()->paintDevice = q;
qctx->d_func()->valid = true;
#if defined(Q_WS_WIN) && !defined(QT_OPENGL_ES)
qctx->d_func()->dc = dc;
qctx->d_func()->rc = ctx;
#elif (defined(Q_WS_X11) && defined(QT_NO_EGL))
qctx->d_func()->cx = ctx;
qctx->d_func()->pbuf = (void *) pbuf;
qctx->d_func()->vi = 0;
#elif defined(Q_WS_MAC)
qctx->d_func()->cx = ctx;
qctx->d_func()->vi = 0;
#elif !defined(QT_NO_EGL)
qctx->d_func()->eglContext = ctx;
qctx->d_func()->eglSurface = pbuf;
#endif
}
}
@ -261,6 +240,8 @@ bool QGLPixelBuffer::doneCurrent()
}
/*!
\fn GLuint QGLPixelBuffer::generateDynamicTexture() const
Generates and binds a 2D GL texture that is the same size as the
pbuffer, and returns the texture's ID. This can be used in
conjunction with bindToDynamicTexture() and
@ -269,20 +250,6 @@ bool QGLPixelBuffer::doneCurrent()
\sa size()
*/
#if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && defined(QT_NO_EGL)
GLuint QGLPixelBuffer::generateDynamicTexture() const
{
Q_D(const QGLPixelBuffer);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return texture;
}
#endif
/*! \fn bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
Binds the texture specified by \a texture_id to this pbuffer.
@ -353,13 +320,6 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
#endif
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
void QGLPixelBuffer::updateDynamicTexture(QMacCompatGLuint texture_id) const
{
updateDynamicTexture(GLuint(texture_id));
}
#endif
/*!
Returns the size of the pbuffer.
*/
@ -402,27 +362,12 @@ bool QGLPixelBuffer::isValid() const
return !d->invalid;
}
#if !defined(QT_OPENGL_ES_1)
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)
#endif
#ifndef QT_OPENGL_ES_2
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_buffer_engine)
#endif
/*! \reimp */
QPaintEngine *QGLPixelBuffer::paintEngine() const
{
#if defined(QT_OPENGL_ES_1)
return qt_buffer_engine()->engine();
#elif defined(QT_OPENGL_ES_2)
return qt_buffer_2_engine()->engine();
#else
if (qt_gl_preferGL2Engine())
return qt_buffer_2_engine()->engine();
else
return qt_buffer_engine()->engine();
#endif
}
/*! \reimp */
@ -493,15 +438,6 @@ GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target)
#endif
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
GLuint QGLPixelBuffer::bindTexture(const QImage &image, QMacCompatGLenum target)
{
Q_D(QGLPixelBuffer);
return d->qctx->bindTexture(image, target, QMacCompatGLint(GL_RGBA8));
}
#endif
/*! \overload
Generates and binds a 2D GL texture based on \a pixmap.
@ -520,15 +456,6 @@ GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target)
#endif
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target)
{
Q_D(QGLPixelBuffer);
return d->qctx->bindTexture(pixmap, target, QMacCompatGLint(GL_RGBA8));
}
#endif
/*! \overload
Reads the DirectDrawSurface (DDS) compressed file \a fileName and
@ -555,15 +482,6 @@ void QGLPixelBuffer::deleteTexture(GLuint texture_id)
d->qctx->deleteTexture(texture_id);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLPixelBuffer::deleteTexture(QMacCompatGLuint texture_id)
{
Q_D(QGLPixelBuffer);
d->qctx->deleteTexture(texture_id);
}
#endif
/*!
\since 4.4
@ -579,15 +497,6 @@ void QGLPixelBuffer::drawTexture(const QRectF &target, GLuint textureId, GLenum
d->qctx->drawTexture(target, textureId, textureTarget);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLPixelBuffer::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
Q_D(QGLPixelBuffer);
d->qctx->drawTexture(target, textureId, textureTarget);
}
#endif
/*!
\since 4.4
@ -602,15 +511,6 @@ void QGLPixelBuffer::drawTexture(const QPointF &point, GLuint textureId, GLenum
d->qctx->drawTexture(point, textureId, textureTarget);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLPixelBuffer::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
Q_D(QGLPixelBuffer);
d->qctx->drawTexture(point, textureId, textureTarget);
}
#endif
/*!
Returns the format of the pbuffer. The format may be different
from the one that was requested.

View File

@ -80,18 +80,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
bool bindToDynamicTexture(QMacCompatGLuint texture);
void updateDynamicTexture(QMacCompatGLuint texture_id) const;
GLuint bindTexture(const QImage &image, QMacCompatGLenum target = GL_TEXTURE_2D);
GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum target = GL_TEXTURE_2D);
void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
void deleteTexture(QMacCompatGLuint texture_id);
#endif
QSize size() const;
Qt::HANDLE handle() const;
QImage toImage() const;

View File

@ -1,224 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qdebug.h>
#include "qglpixelbuffer.h"
#include "qglpixelbuffer_p.h"
#include "qgl_egl_p.h"
#include <qimage.h>
#include <private/qgl_p.h>
QT_BEGIN_NAMESPACE
#ifdef EGL_BIND_TO_TEXTURE_RGBA
#define QGL_RENDER_TEXTURE 1
#else
#define QGL_RENDER_TEXTURE 0
#endif
bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
{
// Create the EGL context.
ctx = new QEglContext();
ctx->setApi(QEgl::OpenGL);
// Find the shared context.
QEglContext *shareContext = 0;
if (shareWidget && shareWidget->d_func()->glcx)
shareContext = shareWidget->d_func()->glcx->d_func()->eglContext;
// Choose an appropriate configuration. We use the best format
// we can find, even if it is greater than the requested format.
// We try for a pbuffer that is capable of texture rendering if possible.
textureFormat = EGL_NONE;
if (shareContext) {
// Use the same configuration as the widget we are sharing with.
ctx->setConfig(shareContext->config());
#if QGL_RENDER_TEXTURE
if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA) == EGL_TRUE)
textureFormat = EGL_TEXTURE_RGBA;
else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB) == EGL_TRUE)
textureFormat = EGL_TEXTURE_RGB;
#endif
} else {
QEglProperties configProps;
qt_eglproperties_set_glformat(configProps, f);
configProps.setDeviceType(QInternal::Pbuffer);
configProps.setRenderableType(ctx->api());
bool ok = false;
#if QGL_RENDER_TEXTURE
textureFormat = EGL_TEXTURE_RGBA;
configProps.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat);
if (!ok) {
// Try again with RGB texture rendering.
textureFormat = EGL_TEXTURE_RGB;
configProps.removeValue(EGL_BIND_TO_TEXTURE_RGBA);
configProps.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat);
if (!ok) {
// One last try for a pbuffer with no texture rendering.
configProps.removeValue(EGL_BIND_TO_TEXTURE_RGB);
textureFormat = EGL_NONE;
}
}
#endif
if (!ok) {
if (!ctx->chooseConfig(configProps, QEgl::BestPixelFormat)) {
delete ctx;
ctx = 0;
return false;
}
}
}
// Retrieve the actual format properties.
qt_glformat_from_eglconfig(format, ctx->config());
// Create the attributes needed for the pbuffer.
QEglProperties attribs;
attribs.setValue(EGL_WIDTH, size.width());
attribs.setValue(EGL_HEIGHT, size.height());
#if QGL_RENDER_TEXTURE
if (textureFormat != EGL_NONE) {
attribs.setValue(EGL_TEXTURE_FORMAT, textureFormat);
attribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D);
}
#endif
// Create the pbuffer surface.
pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties());
#if QGL_RENDER_TEXTURE
if (pbuf == EGL_NO_SURFACE && textureFormat != EGL_NONE) {
// Try again with texture rendering disabled.
textureFormat = EGL_NONE;
attribs.removeValue(EGL_TEXTURE_FORMAT);
attribs.removeValue(EGL_TEXTURE_TARGET);
pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties());
}
#endif
if (pbuf == EGL_NO_SURFACE) {
qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEgl::errorString();
return false;
}
// Create a new context for the configuration.
if (!ctx->createContext(shareContext)) {
delete ctx;
ctx = 0;
return false;
}
return true;
}
bool QGLPixelBufferPrivate::cleanup()
{
// No need to destroy "pbuf" here - it is done in QGLContext::reset().
return true;
}
bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
{
#if QGL_RENDER_TEXTURE
Q_D(QGLPixelBuffer);
if (d->invalid || d->textureFormat == EGL_NONE || !d->ctx)
return false;
glBindTexture(GL_TEXTURE_2D, texture_id);
return eglBindTexImage(d->ctx->display(), d->pbuf, EGL_BACK_BUFFER);
#else
Q_UNUSED(texture_id);
return false;
#endif
}
void QGLPixelBuffer::releaseFromDynamicTexture()
{
#if QGL_RENDER_TEXTURE
Q_D(QGLPixelBuffer);
if (d->invalid || d->textureFormat == EGL_NONE || !d->ctx)
return;
eglReleaseTexImage(d->ctx->display(), d->pbuf, EGL_BACK_BUFFER);
#endif
}
GLuint QGLPixelBuffer::generateDynamicTexture() const
{
#if QGL_RENDER_TEXTURE
Q_D(const QGLPixelBuffer);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
if (d->textureFormat == EGL_TEXTURE_RGB)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, d->req_size.width(), d->req_size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return texture;
#else
return 0;
#endif
}
bool QGLPixelBuffer::hasOpenGLPbuffers()
{
// See if we have at least 1 configuration that matches the default format.
EGLDisplay dpy = QEgl::display();
if (dpy == EGL_NO_DISPLAY)
return false;
QEglProperties configProps;
qt_eglproperties_set_glformat(configProps, QGLFormat::defaultFormat());
configProps.setDeviceType(QInternal::Pbuffer);
configProps.setRenderableType(QEgl::OpenGL);
do {
EGLConfig cfg = 0;
EGLint matching = 0;
if (eglChooseConfig(dpy, configProps.properties(),
&cfg, 1, &matching) && matching > 0)
return true;
} while (configProps.reduceConfiguration());
return false;
}
QT_END_NAMESPACE

View File

@ -1,331 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qglpixelbuffer.h"
#include "qglpixelbuffer_p.h"
#ifndef QT_MAC_USE_COCOA
#include <AGL/agl.h>
#endif
#include <qimage.h>
#include <private/qgl_p.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
#ifndef GL_TEXTURE_RECTANGLE_EXT
#define GL_TEXTURE_RECTANGLE_EXT 0x84F5
#endif
static int nearest_gl_texture_size(int v)
{
int n = 0, last = 0;
for (int s = 0; s < 32; ++s) {
if (((v>>s) & 1) == 1) {
++n;
last = s;
}
}
if (n > 1)
return 1 << (last+1);
return 1 << last;
}
bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
{
#ifdef QT_MAC_USE_COCOA
Q_Q(QGLPixelBuffer);
// create a dummy context
QGLContext context(f, q);
context.create(shareWidget ? shareWidget->context() : 0);
if (context.isSharing())
share_ctx = shareWidget->context()->d_func()->cx;
// steal the NSOpenGLContext and update the format
ctx = context.d_func()->cx;
context.d_func()->cx = 0;
// d->cx will be set to ctx later in
// QGLPixelBufferPrivate::common_init, so we need to retain it:
[static_cast<NSOpenGLContext *>(ctx) retain];
format = context.format();
GLenum target = GL_TEXTURE_2D;
if ((QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
&& (size.width() != nearest_gl_texture_size(size.width())
|| size.height() != nearest_gl_texture_size(size.height())))
{
target = GL_TEXTURE_RECTANGLE_EXT;
}
pbuf = [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:target
textureInternalFormat:GL_RGBA
textureMaxMipMapLevel:0
pixelsWide:size.width()
pixelsHigh:size.height()];
if (!pbuf) {
qWarning("QGLPixelBuffer: Cannot create a pbuffer");
return false;
}
[static_cast<NSOpenGLContext *>(ctx) setPixelBuffer:static_cast<NSOpenGLPixelBuffer *>(pbuf)
cubeMapFace:0
mipMapLevel:0
currentVirtualScreen:0];
return true;
#else
GLint attribs[40], i=0;
attribs[i++] = AGL_RGBA;
attribs[i++] = AGL_BUFFER_SIZE;
attribs[i++] = 32;
attribs[i++] = AGL_LEVEL;
attribs[i++] = f.plane();
if (f.redBufferSize() != -1) {
attribs[i++] = AGL_RED_SIZE;
attribs[i++] = f.redBufferSize();
}
if (f.greenBufferSize() != -1) {
attribs[i++] = AGL_GREEN_SIZE;
attribs[i++] = f.greenBufferSize();
}
if (f.blueBufferSize() != -1) {
attribs[i++] = AGL_BLUE_SIZE;
attribs[i++] = f.blueBufferSize();
}
if (f.stereo())
attribs[i++] = AGL_STEREO;
if (f.alpha()) {
attribs[i++] = AGL_ALPHA_SIZE;
attribs[i++] = f.alphaBufferSize() == -1 ? 8 : f.alphaBufferSize();
}
if (f.stencil()) {
attribs[i++] = AGL_STENCIL_SIZE;
attribs[i++] = f.stencilBufferSize() == -1 ? 8 : f.stencilBufferSize();
}
if (f.depth()) {
attribs[i++] = AGL_DEPTH_SIZE;
attribs[i++] = f.depthBufferSize() == -1 ? 32 : f.depthBufferSize();
}
if (f.accum()) {
attribs[i++] = AGL_ACCUM_RED_SIZE;
attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
attribs[i++] = AGL_ACCUM_BLUE_SIZE;
attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
attribs[i++] = AGL_ACCUM_GREEN_SIZE;
attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
attribs[i++] = AGL_ACCUM_ALPHA_SIZE;
attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
}
if (f.sampleBuffers()) {
attribs[i++] = AGL_SAMPLE_BUFFERS_ARB;
attribs[i++] = 1;
attribs[i++] = AGL_SAMPLES_ARB;
attribs[i++] = f.samples() == -1 ? 4 : f.samples();
}
attribs[i] = AGL_NONE;
AGLPixelFormat format = aglChoosePixelFormat(0, 0, attribs);
if (!format) {
qWarning("QGLPixelBuffer: Unable to find a pixel format (AGL error %d).",
(int) aglGetError());
return false;
}
GLint res;
aglDescribePixelFormat(format, AGL_LEVEL, &res);
this->format.setPlane(res);
aglDescribePixelFormat(format, AGL_DOUBLEBUFFER, &res);
this->format.setDoubleBuffer(res);
aglDescribePixelFormat(format, AGL_DEPTH_SIZE, &res);
this->format.setDepth(res);
if (this->format.depth())
this->format.setDepthBufferSize(res);
aglDescribePixelFormat(format, AGL_RGBA, &res);
this->format.setRgba(res);
aglDescribePixelFormat(format, AGL_RED_SIZE, &res);
this->format.setRedBufferSize(res);
aglDescribePixelFormat(format, AGL_GREEN_SIZE, &res);
this->format.setGreenBufferSize(res);
aglDescribePixelFormat(format, AGL_BLUE_SIZE, &res);
this->format.setBlueBufferSize(res);
aglDescribePixelFormat(format, AGL_ALPHA_SIZE, &res);
this->format.setAlpha(res);
if (this->format.alpha())
this->format.setAlphaBufferSize(res);
aglDescribePixelFormat(format, AGL_ACCUM_RED_SIZE, &res);
this->format.setAccum(res);
if (this->format.accum())
this->format.setAccumBufferSize(res);
aglDescribePixelFormat(format, AGL_STENCIL_SIZE, &res);
this->format.setStencil(res);
if (this->format.stencil())
this->format.setStencilBufferSize(res);
aglDescribePixelFormat(format, AGL_STEREO, &res);
this->format.setStereo(res);
aglDescribePixelFormat(format, AGL_SAMPLE_BUFFERS_ARB, &res);
this->format.setSampleBuffers(res);
if (this->format.sampleBuffers()) {
aglDescribePixelFormat(format, AGL_SAMPLES_ARB, &res);
this->format.setSamples(res);
}
AGLContext share = 0;
if (shareWidget)
share = share_ctx = static_cast<AGLContext>(shareWidget->d_func()->glcx->d_func()->cx);
ctx = aglCreateContext(format, share);
if (!ctx) {
qWarning("QGLPixelBuffer: Unable to create a context (AGL error %d).",
(int) aglGetError());
return false;
}
GLenum target = GL_TEXTURE_2D;
if ((QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
&& (size.width() != nearest_gl_texture_size(size.width())
|| size.height() != nearest_gl_texture_size(size.height())))
{
target = GL_TEXTURE_RECTANGLE_EXT;
}
if (!aglCreatePBuffer(size.width(), size.height(), target, GL_RGBA, 0, &pbuf)) {
qWarning("QGLPixelBuffer: Unable to create a pbuffer (AGL error %d).",
(int) aglGetError());
return false;
}
if (!aglSetPBuffer(ctx, pbuf, 0, 0, 0)) {
qWarning("QGLPixelBuffer: Unable to set pbuffer (AGL error %d).",
(int) aglGetError());
return false;
}
aglDestroyPixelFormat(format);
return true;
#endif
}
bool QGLPixelBufferPrivate::cleanup()
{
#ifdef QT_MAC_USE_COCOA
[static_cast<NSOpenGLPixelBuffer *>(pbuf) release];
pbuf = 0;
[static_cast<NSOpenGLContext *>(ctx) release];
ctx = 0;
#else
aglDestroyPBuffer(pbuf);
#endif
return true;
}
bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
{
Q_D(QGLPixelBuffer);
if (d->invalid || !d->share_ctx)
return false;
#ifdef QT_MAC_USE_COCOA
NSOpenGLContext *oldContext = [NSOpenGLContext currentContext];
if (d->share_ctx != oldContext)
[static_cast<NSOpenGLContext *>(d->share_ctx) makeCurrentContext];
glBindTexture(GL_TEXTURE_2D, texture_id);
[static_cast<NSOpenGLContext *>(d->share_ctx)
setTextureImageToPixelBuffer:static_cast<NSOpenGLPixelBuffer *>(d->pbuf)
colorBuffer:GL_FRONT];
if (oldContext && oldContext != d->share_ctx)
[oldContext makeCurrentContext];
return true;
#else
aglSetCurrentContext(d->share_ctx);
glBindTexture(GL_TEXTURE_2D, texture_id);
aglTexImagePBuffer(d->share_ctx, d->pbuf, GL_FRONT);
return true;
#endif
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
bool QGLPixelBuffer::bindToDynamicTexture(QMacCompatGLuint texture_id)
{
return bindToDynamicTexture(GLuint(texture_id));
}
#endif
void QGLPixelBuffer::releaseFromDynamicTexture()
{
}
GLuint QGLPixelBuffer::generateDynamicTexture() const
{
#ifdef QT_MAC_USE_COCOA
Q_D(const QGLPixelBuffer);
NSOpenGLContext *oldContext = [NSOpenGLContext currentContext];
if (d->share_ctx != oldContext)
[static_cast<NSOpenGLContext *>(d->share_ctx) makeCurrentContext];
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (oldContext && oldContext != d->share_ctx)
[oldContext makeCurrentContext];
return texture;
#else
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return texture;
#endif
}
bool QGLPixelBuffer::hasOpenGLPbuffers()
{
return true;
}
QT_END_NAMESPACE

View File

@ -59,77 +59,6 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include "QtOpenGL/qglpixelbuffer.h"
#include <private/qgl_p.h>
#include <private/qglpaintdevice_p.h>
#if defined(Q_WS_X11) && defined(QT_NO_EGL)
#include <GL/glx.h>
// The below is needed to for compilation on HPUX, due to broken GLX
// headers. Some of the systems define GLX_VERSION_1_3 without
// defining the GLXFBConfig structure, which is wrong.
#if defined (Q_OS_HPUX) && defined(QT_DEFINE_GLXFBCONFIG_STRUCT)
typedef unsigned long GLXPbuffer;
struct GLXFBConfig {
int visualType;
int transparentType;
/* colors are floats scaled to ints */
int transparentRed, transparentGreen, transparentBlue, transparentAlpha;
int transparentIndex;
int visualCaveat;
int associatedVisualId;
int screen;
int drawableType;
int renderType;
int maxPbufferWidth, maxPbufferHeight, maxPbufferPixels;
int optimalPbufferWidth, optimalPbufferHeight; /* for SGIX_pbuffer */
int visualSelectGroup; /* visuals grouped by select priority */
unsigned int id;
GLboolean rgbMode;
GLboolean colorIndexMode;
GLboolean doubleBufferMode;
GLboolean stereoMode;
GLboolean haveAccumBuffer;
GLboolean haveDepthBuffer;
GLboolean haveStencilBuffer;
/* The number of bits present in various buffers */
GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
GLint depthBits;
GLint stencilBits;
GLint indexBits;
GLint redBits, greenBits, blueBits, alphaBits;
GLuint redMask, greenMask, blueMask, alphaMask;
GLuint multiSampleSize; /* Number of samples per pixel (0 if no ms) */
GLuint nMultiSampleBuffers; /* Number of available ms buffers */
GLint maxAuxBuffers;
/* frame buffer level */
GLint level;
/* color ranges (for SGI_color_range) */
GLboolean extendedRange;
GLdouble minRed, maxRed;
GLdouble minGreen, maxGreen;
GLdouble minBlue, maxBlue;
GLdouble minAlpha, maxAlpha;
};
#endif // Q_OS_HPUX
#elif defined(Q_OS_WIN)
DECLARE_HANDLE(HPBUFFERARB);
#elif !defined(QT_NO_EGL)
#include <QtGui/private/qegl_p.h>
#endif
QT_END_INCLUDE_NAMESPACE
class QEglContext;
@ -152,11 +81,6 @@ class QGLPixelBufferPrivate {
public:
QGLPixelBufferPrivate(QGLPixelBuffer *q) : q_ptr(q), invalid(true), qctx(0), pbuf(0), ctx(0)
{
#ifdef Q_WS_WIN
dc = 0;
#elif defined(Q_WS_MACX)
share_ctx = 0;
#endif
}
bool init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget);
void common_init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget);
@ -172,36 +96,9 @@ public:
QPointer<QGLWidget> req_shareWidget;
QSize req_size;
#if defined(Q_WS_X11) && defined(QT_NO_EGL)
GLXPbuffer pbuf;
GLXContext ctx;
#elif defined(Q_WS_WIN)
HDC dc;
bool has_render_texture :1;
#if !defined(QT_OPENGL_ES)
HPBUFFERARB pbuf;
HGLRC ctx;
#endif
#elif defined(Q_WS_MACX)
# ifdef QT_MAC_USE_COCOA
void *pbuf;
void *ctx;
void *share_ctx;
# else
AGLPbuffer pbuf;
AGLContext ctx;
AGLContext share_ctx;
# endif
#endif
#ifndef QT_NO_EGL
EGLSurface pbuf;
QEglContext *ctx;
int textureFormat;
#elif defined(Q_WS_QPA)
//stubs
void *pbuf;
void *ctx;
#endif
};
QT_END_NAMESPACE

View File

@ -1,403 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qglpixelbuffer.h>
#include <qgl.h>
#include <private/qgl_p.h>
#include <private/qglpixelbuffer_p.h>
#include <qimage.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
/* WGL_WGLEXT_PROTOTYPES */
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int * piAttribList);
#ifndef WGL_ARB_pbuffer
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
#define WGL_PBUFFER_LARGEST_ARB 0x2033
#define WGL_PBUFFER_WIDTH_ARB 0x2034
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
#define WGL_PBUFFER_LOST_ARB 0x2036
#endif
#ifndef WGL_ARB_pixel_format
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NEED_PALETTE_ARB 0x2004
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
#define WGL_TRANSPARENT_ARB 0x200A
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
#define WGL_SHARE_DEPTH_ARB 0x200C
#define WGL_SHARE_STENCIL_ARB 0x200D
#define WGL_SHARE_ACCUM_ARB 0x200E
#define WGL_SUPPORT_GDI_ARB 0x200F
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201A
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_ALPHA_SHIFT_ARB 0x201C
#define WGL_ACCUM_BITS_ARB 0x201D
#define WGL_ACCUM_RED_BITS_ARB 0x201E
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_SWAP_COPY_ARB 0x2029
#define WGL_SWAP_UNDEFINED_ARB 0x202A
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_TYPE_COLORINDEX_ARB 0x202C
#endif
#ifndef WGL_ARB_render_texture
#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
#define WGL_TEXTURE_FORMAT_ARB 0x2072
#define WGL_TEXTURE_TARGET_ARB 0x2073
#define WGL_MIPMAP_TEXTURE_ARB 0x2074
#define WGL_TEXTURE_RGB_ARB 0x2075
#define WGL_TEXTURE_RGBA_ARB 0x2076
#define WGL_NO_TEXTURE_ARB 0x2077
#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
#define WGL_TEXTURE_1D_ARB 0x2079
#define WGL_TEXTURE_2D_ARB 0x207A
#define WGL_MIPMAP_LEVEL_ARB 0x207B
#define WGL_CUBE_MAP_FACE_ARB 0x207C
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
#define WGL_FRONT_LEFT_ARB 0x2083
#define WGL_FRONT_RIGHT_ARB 0x2084
#define WGL_BACK_LEFT_ARB 0x2085
#define WGL_BACK_RIGHT_ARB 0x2086
#define WGL_AUX0_ARB 0x2087
#define WGL_AUX1_ARB 0x2088
#define WGL_AUX2_ARB 0x2089
#define WGL_AUX3_ARB 0x208A
#define WGL_AUX4_ARB 0x208B
#define WGL_AUX5_ARB 0x208C
#define WGL_AUX6_ARB 0x208D
#define WGL_AUX7_ARB 0x208E
#define WGL_AUX8_ARB 0x208F
#define WGL_AUX9_ARB 0x2090
#endif
#ifndef WGL_FLOAT_COMPONENTS_NV
#define WGL_FLOAT_COMPONENTS_NV 0x20B0
#endif
#ifndef WGL_ARB_multisample
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
#endif
#ifndef GL_SAMPLES_ARB
#define GL_SAMPLES_ARB 0x80A9
#endif
QGLFormat pfiToQGLFormat(HDC hdc, int pfi);
static void qt_format_to_attrib_list(bool has_render_texture, const QGLFormat &f, int attribs[])
{
int i = 0;
attribs[i++] = WGL_SUPPORT_OPENGL_ARB;
attribs[i++] = TRUE;
attribs[i++] = WGL_DRAW_TO_PBUFFER_ARB;
attribs[i++] = TRUE;
if (has_render_texture) {
attribs[i++] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
attribs[i++] = TRUE;
}
attribs[i++] = WGL_COLOR_BITS_ARB;
attribs[i++] = 32;
attribs[i++] = WGL_DOUBLE_BUFFER_ARB;
attribs[i++] = FALSE;
if (f.stereo()) {
attribs[i++] = WGL_STEREO_ARB;
attribs[i++] = TRUE;
}
if (f.depth()) {
attribs[i++] = WGL_DEPTH_BITS_ARB;
attribs[i++] = f.depthBufferSize() == -1 ? 24 : f.depthBufferSize();
}
if (f.redBufferSize() != -1) {
attribs[i++] = WGL_RED_BITS_ARB;
attribs[i++] = f.redBufferSize();
}
if (f.greenBufferSize() != -1) {
attribs[i++] = WGL_GREEN_BITS_ARB;
attribs[i++] = f.greenBufferSize();
}
if (f.blueBufferSize() != -1) {
attribs[i++] = WGL_BLUE_BITS_ARB;
attribs[i++] = f.blueBufferSize();
}
if (f.alpha()) {
attribs[i++] = WGL_ALPHA_BITS_ARB;
attribs[i++] = f.alphaBufferSize() == -1 ? 8 : f.alphaBufferSize();
}
if (f.accum()) {
attribs[i++] = WGL_ACCUM_BITS_ARB;
attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
}
if (f.stencil()) {
attribs[i++] = WGL_STENCIL_BITS_ARB;
attribs[i++] = f.stencilBufferSize() == -1 ? 8 : f.stencilBufferSize();
}
if ((f.redBufferSize() > 8 || f.greenBufferSize() > 8
|| f.blueBufferSize() > 8 || f.alphaBufferSize() > 8)
&& (QGLExtensions::glExtensions() & QGLExtensions::NVFloatBuffer))
{
attribs[i++] = WGL_FLOAT_COMPONENTS_NV;
attribs[i++] = TRUE;
}
if (f.sampleBuffers()) {
attribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
attribs[i++] = 1;
attribs[i++] = WGL_SAMPLES_ARB;
attribs[i++] = f.samples() == -1 ? 16 : f.samples();
}
attribs[i] = 0;
}
bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
{
QGLTemporaryContext tempContext;
PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB =
(PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB =
(PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB =
(PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
(PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
if (!wglCreatePbufferARB) // assumes that if one can be resolved, all of them can
return false;
dc = wglGetCurrentDC();
Q_ASSERT(dc);
has_render_texture = false;
// sample buffers doesn't work in conjunction with the render_texture extension
if (!f.sampleBuffers()) {
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
(PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
if (wglGetExtensionsStringARB) {
QString extensions(QLatin1String(wglGetExtensionsStringARB(dc)));
has_render_texture = extensions.contains(QLatin1String("WGL_ARB_render_texture"));
}
}
int attribs[40];
qt_format_to_attrib_list(has_render_texture, f, attribs);
// Find pbuffer capable pixel format.
unsigned int num_formats = 0;
int pixel_format;
wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);
// some GL implementations don't support pbuffers with accum
// buffers, so try that before we give up
if (num_formats == 0 && f.accum()) {
QGLFormat tmp = f;
tmp.setAccum(false);
qt_format_to_attrib_list(has_render_texture, tmp, attribs);
wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);
}
if (num_formats == 0) {
qWarning("QGLPixelBuffer: Unable to find a pixel format with pbuffer - giving up.");
return false;
}
format = pfiToQGLFormat(dc, pixel_format);
// NB! The below ONLY works if the width/height are powers of 2.
// Set some pBuffer attributes so that we can use this pBuffer as
// a 2D RGBA texture target.
int pb_attribs[] = {WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, 0};
pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(),
has_render_texture ? pb_attribs : 0);
if (!pbuf) {
// try again without the render_texture extension
pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(), 0);
has_render_texture = false;
if (!pbuf) {
qWarning("QGLPixelBuffer: Unable to create pbuffer [w=%d, h=%d] - giving up.", size.width(), size.height());
return false;
}
}
dc = wglGetPbufferDCARB(pbuf);
ctx = wglCreateContext(dc);
if (!dc || !ctx) {
qWarning("QGLPixelBuffer: Unable to create pbuffer context - giving up.");
return false;
}
// Explicitly disable the render_texture extension if we have a
// multi-sampled pbuffer context. This seems to be a problem only with
// ATI cards if multi-sampling is forced globally in the driver.
wglMakeCurrent(dc, ctx);
GLint samples = 0;
glGetIntegerv(GL_SAMPLES_ARB, &samples);
if (has_render_texture && samples != 0)
has_render_texture = false;
HGLRC share_ctx = shareWidget ? shareWidget->d_func()->glcx->d_func()->rc : 0;
if (share_ctx && !wglShareLists(share_ctx, ctx))
qWarning("QGLPixelBuffer: Unable to share display lists - with share widget.");
int width, height;
wglQueryPbufferARB(pbuf, WGL_PBUFFER_WIDTH_ARB, &width);
wglQueryPbufferARB(pbuf, WGL_PBUFFER_HEIGHT_ARB, &height);
return true;
}
bool QGLPixelBufferPrivate::cleanup()
{
PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB =
(PFNWGLRELEASEPBUFFERDCARBPROC) wglGetProcAddress("wglReleasePbufferDCARB");
PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB =
(PFNWGLDESTROYPBUFFERARBPROC) wglGetProcAddress("wglDestroyPbufferARB");
if (!invalid && wglReleasePbufferDCARB && wglDestroyPbufferARB) {
wglReleasePbufferDCARB(pbuf, dc);
wglDestroyPbufferARB(pbuf);
}
return true;
}
bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
{
Q_D(QGLPixelBuffer);
if (d->invalid || !d->has_render_texture)
return false;
PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB =
(PFNWGLBINDTEXIMAGEARBPROC) wglGetProcAddress("wglBindTexImageARB");
if (wglBindTexImageARB) {
glBindTexture(GL_TEXTURE_2D, texture_id);
return wglBindTexImageARB(d->pbuf, WGL_FRONT_LEFT_ARB);
}
return false;
}
void QGLPixelBuffer::releaseFromDynamicTexture()
{
Q_D(QGLPixelBuffer);
if (d->invalid || !d->has_render_texture)
return;
PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB =
(PFNWGLRELEASETEXIMAGEARBPROC) wglGetProcAddress("wglReleaseTexImageARB");
if (wglReleaseTexImageARB)
wglReleaseTexImageARB(d->pbuf, WGL_FRONT_LEFT_ARB);
}
bool QGLPixelBuffer::hasOpenGLPbuffers()
{
bool ret = false;
QGLTemporaryContext *tmpContext = 0;
if (!QGLContext::currentContext())
tmpContext = new QGLTemporaryContext;
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
(PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
if (wglGetExtensionsStringARB) {
QString extensions(QLatin1String(wglGetExtensionsStringARB(wglGetCurrentDC())));
if (extensions.contains(QLatin1String("WGL_ARB_pbuffer"))
&& extensions.contains(QLatin1String("WGL_ARB_pixel_format"))) {
ret = true;
}
}
if (tmpContext)
delete tmpContext;
return ret;
}
QT_END_NAMESPACE

View File

@ -1,290 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qlibrary.h>
#include <qdebug.h>
#include <private/qgl_p.h>
#include <private/qt_x11_p.h>
#include <private/qpaintengine_opengl_p.h>
#include <qx11info_x11.h>
#include <GL/glx.h>
#include <qimage.h>
#include "qglpixelbuffer.h"
#include "qglpixelbuffer_p.h"
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
#include <dlfcn.h>
#endif
QT_BEGIN_NAMESPACE
#ifndef GLX_VERSION_1_3
#define GLX_RGBA_BIT 0x00000002
#define GLX_PBUFFER_BIT 0x00000004
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_RGBA_TYPE 0x8014
#define GLX_PBUFFER_HEIGHT 0x8040
#define GLX_PBUFFER_WIDTH 0x8041
#endif
#ifndef GLX_ARB_multisample
#define GLX_SAMPLE_BUFFERS_ARB 100000
#define GLX_SAMPLES_ARB 100001
#endif
typedef GLXFBConfig* (*_glXChooseFBConfig) (Display *dpy, int screen, const int *attrib_list, int *nelements);
typedef int (*_glXGetFBConfigAttrib) (Display *dpy, GLXFBConfig config, int attribute, int *value);
typedef GLXPbuffer (*_glXCreatePbuffer) (Display *dpy, GLXFBConfig config, const int *attrib_list);
typedef void (*_glXDestroyPbuffer) (Display *dpy, GLXPbuffer pbuf);
typedef GLXContext (*_glXCreateNewContext) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
typedef Bool (*_glXMakeContextCurrent) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
static _glXChooseFBConfig qt_glXChooseFBConfig = 0;
static _glXCreateNewContext qt_glXCreateNewContext = 0;
static _glXCreatePbuffer qt_glXCreatePbuffer = 0;
static _glXDestroyPbuffer qt_glXDestroyPbuffer = 0;
static _glXGetFBConfigAttrib qt_glXGetFBConfigAttrib = 0;
static _glXMakeContextCurrent qt_glXMakeContextCurrent = 0;
#define glXChooseFBConfig qt_glXChooseFBConfig
#define glXCreateNewContext qt_glXCreateNewContext
#define glXCreatePbuffer qt_glXCreatePbuffer
#define glXDestroyPbuffer qt_glXDestroyPbuffer
#define glXGetFBConfigAttrib qt_glXGetFBConfigAttrib
#define glXMakeContextCurrent qt_glXMakeContextCurrent
extern void (*qglx_getProcAddress(const char* procName))(); // in qgl_x11.cpp
static bool qt_resolve_pbuffer_extensions()
{
static int resolved = false;
if (resolved && qt_glXMakeContextCurrent)
return true;
else if (resolved)
return false;
qt_glXChooseFBConfig = (_glXChooseFBConfig) qglx_getProcAddress("glXChooseFBConfig");
qt_glXCreateNewContext = (_glXCreateNewContext) qglx_getProcAddress("glXCreateNewContext");
qt_glXCreatePbuffer = (_glXCreatePbuffer) qglx_getProcAddress("glXCreatePbuffer");
qt_glXDestroyPbuffer = (_glXDestroyPbuffer) qglx_getProcAddress("glXDestroyPbuffer");
qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) qglx_getProcAddress("glXGetFBConfigAttrib");
qt_glXMakeContextCurrent = (_glXMakeContextCurrent) qglx_getProcAddress("glXMakeContextCurrent");
resolved = qt_glXMakeContextCurrent ? true : false;
return resolved;
}
static void qt_format_to_attrib_list(const QGLFormat &f, int attribs[])
{
int i = 0;
attribs[i++] = GLX_RENDER_TYPE;
attribs[i++] = GLX_RGBA_BIT;
attribs[i++] = GLX_DRAWABLE_TYPE;
attribs[i++] = GLX_PBUFFER_BIT;
attribs[i++] = GLX_RED_SIZE;
attribs[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
attribs[i++] = GLX_GREEN_SIZE;
attribs[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize();
attribs[i++] = GLX_BLUE_SIZE;
attribs[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize();
if (f.doubleBuffer()) {
attribs[i++] = GLX_DOUBLEBUFFER;
attribs[i++] = true;
}
if (f.depth()) {
attribs[i++] = GLX_DEPTH_SIZE;
attribs[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize();
}
if (f.stereo()) {
attribs[i++] = GLX_STEREO;
attribs[i++] = true;
}
if (f.stencil()) {
attribs[i++] = GLX_STENCIL_SIZE;
attribs[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize();
}
if (f.alpha()) {
attribs[i++] = GLX_ALPHA_SIZE;
attribs[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize();
}
if (f.accum()) {
attribs[i++] = GLX_ACCUM_RED_SIZE;
attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
attribs[i++] = GLX_ACCUM_GREEN_SIZE;
attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
attribs[i++] = GLX_ACCUM_BLUE_SIZE;
attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
if (f.alpha()) {
attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
}
}
if (f.sampleBuffers()) {
attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
attribs[i++] = 1;
attribs[i++] = GLX_SAMPLES_ARB;
attribs[i++] = f.samples() == -1 ? 4 : f.samples();
}
attribs[i] = XNone;
}
bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
{
if (!qt_resolve_pbuffer_extensions()) {
qWarning("QGLPixelBuffer: pbuffers are not supported on this system.");
return false;
}
int attribs[40];
int num_configs = 0;
qt_format_to_attrib_list(f, attribs);
int screen = X11->defaultScreen;
if (shareWidget)
screen = shareWidget->x11Info().screen();
GLXFBConfig *configs = glXChooseFBConfig(X11->display, screen, attribs, &num_configs);
if (configs && num_configs) {
int res;
glXGetFBConfigAttrib(X11->display, configs[0], GLX_LEVEL, &res);
format.setPlane(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_DOUBLEBUFFER, &res);
format.setDoubleBuffer(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_DEPTH_SIZE, &res);
format.setDepth(res);
if (format.depth())
format.setDepthBufferSize(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_RGBA, &res);
format.setRgba(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_RED_SIZE, &res);
format.setRedBufferSize(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_GREEN_SIZE, &res);
format.setGreenBufferSize(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_BLUE_SIZE, &res);
format.setBlueBufferSize(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_ALPHA_SIZE, &res);
format.setAlpha(res);
if (format.alpha())
format.setAlphaBufferSize(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_ACCUM_RED_SIZE, &res);
format.setAccum(res);
if (format.accum())
format.setAccumBufferSize(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_STENCIL_SIZE, &res);
format.setStencil(res);
if (format.stencil())
format.setStencilBufferSize(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_STEREO, &res);
format.setStereo(res);
glXGetFBConfigAttrib(X11->display, configs[0], GLX_SAMPLE_BUFFERS_ARB, &res);
format.setSampleBuffers(res);
if (format.sampleBuffers()) {
glXGetFBConfigAttrib(X11->display, configs[0], GLX_SAMPLES_ARB, &res);
format.setSamples(res);
}
int pb_attribs[] = {GLX_PBUFFER_WIDTH, size.width(), GLX_PBUFFER_HEIGHT, size.height(), XNone};
GLXContext shareContext = 0;
if (shareWidget && shareWidget->d_func()->glcx)
shareContext = (GLXContext) shareWidget->d_func()->glcx->d_func()->cx;
pbuf = glXCreatePbuffer(QX11Info::display(), configs[0], pb_attribs);
ctx = glXCreateNewContext(QX11Info::display(), configs[0], GLX_RGBA_TYPE, shareContext, true);
XFree(configs);
if (!pbuf || !ctx) {
qWarning("QGLPixelBuffer: Unable to create a pbuffer/context - giving up.");
return false;
}
return true;
} else {
qWarning("QGLPixelBuffer: Unable to find a context/format match - giving up.");
return false;
}
}
bool QGLPixelBufferPrivate::cleanup()
{
glXDestroyPbuffer(QX11Info::display(), pbuf);
return true;
}
bool QGLPixelBuffer::bindToDynamicTexture(GLuint)
{
return false;
}
void QGLPixelBuffer::releaseFromDynamicTexture()
{
}
bool QGLPixelBuffer::hasOpenGLPbuffers()
{
bool ret = qt_resolve_pbuffer_extensions();
if (!ret)
return false;
int attribs[40];
int num_configs = 0;
qt_format_to_attrib_list(QGLFormat::defaultFormat(), attribs);
GLXFBConfig *configs = glXChooseFBConfig(X11->display, X11->defaultScreen, attribs, &num_configs);
GLXPbuffer pbuf = 0;
GLXContext ctx = 0;
if (configs && num_configs) {
int pb_attribs[] = {GLX_PBUFFER_WIDTH, 128, GLX_PBUFFER_HEIGHT, 128, XNone};
pbuf = glXCreatePbuffer(X11->display, configs[0], pb_attribs);
ctx = glXCreateNewContext(X11->display, configs[0], GLX_RGBA_TYPE, 0, true);
XFree(configs);
glXDestroyContext(X11->display, ctx);
glXDestroyPbuffer(X11->display, pbuf);
}
return pbuf && ctx;
}
QT_END_NAMESPACE

View File

@ -1,619 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "private/qpixmapfilter_p.h"
#include "private/qpaintengineex_opengl2_p.h"
#include "private/qglengineshadermanager_p.h"
#include "qplatformpixmap_qpa.h"
#include "private/qimagepixmapcleanuphooks_p.h"
#include "qglpixmapfilter_p.h"
#include "qpaintengine_opengl_p.h"
#include "qcache.h"
#include "qglframebufferobject.h"
#include "qglshaderprogram.h"
#include "qgl_p.h"
#include "private/qapplication_p.h"
#include "private/qdrawhelper_p.h"
#include "private/qmemrotate_p.h"
#include "private/qmath_p.h"
#include "qmath.h"
QT_BEGIN_NAMESPACE
// qpixmapfilter.cpp
Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);
Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source);
void QGLPixmapFilterBase::bindTexture(const QPixmap &src) const
{
const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA, QGLContext::BindOptions(QGLContext::DefaultBindOption | QGLContext::MemoryManagedBindOption));
}
void QGLPixmapFilterBase::drawImpl(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF& source) const
{
processGL(painter, pos, src, source);
}
class QGLPixmapColorizeFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapColorizeFilter>
{
public:
QGLPixmapColorizeFilter();
void setUniforms(QGLShaderProgram *program);
protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &pixmap, const QRectF &srcRect) const;
};
class QGLPixmapConvolutionFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapConvolutionFilter>
{
public:
QGLPixmapConvolutionFilter();
~QGLPixmapConvolutionFilter();
void setUniforms(QGLShaderProgram *program);
protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
private:
QByteArray generateConvolutionShader() const;
mutable QSize m_srcSize;
mutable int m_prevKernelSize;
};
class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapBlurFilter>
{
public:
QGLPixmapBlurFilter();
protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
};
class QGLPixmapDropShadowFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapDropShadowFilter>
{
public:
QGLPixmapDropShadowFilter();
void setUniforms(QGLShaderProgram *program);
protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
};
extern const QGLContext *qt_gl_share_context();
QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *prototype)
{
Q_D(QGL2PaintEngineEx);
switch (type) {
case QPixmapFilter::ColorizeFilter:
if (!d->colorizeFilter)
d->colorizeFilter.reset(new QGLPixmapColorizeFilter);
return d->colorizeFilter.data();
case QPixmapFilter::BlurFilter: {
if (!d->blurFilter)
d->blurFilter.reset(new QGLPixmapBlurFilter());
return d->blurFilter.data();
}
case QPixmapFilter::DropShadowFilter: {
if (!d->dropShadowFilter)
d->dropShadowFilter.reset(new QGLPixmapDropShadowFilter());
return d->dropShadowFilter.data();
}
case QPixmapFilter::ConvolutionFilter:
if (!d->convolutionFilter)
d->convolutionFilter.reset(new QGLPixmapConvolutionFilter);
return d->convolutionFilter.data();
default: break;
}
return QPaintEngineEx::pixmapFilter(type, prototype);
}
static const char *qt_gl_colorize_filter =
"uniform lowp vec4 colorizeColor;"
"uniform lowp float colorizeStrength;"
"lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
"{"
" lowp vec4 srcPixel = texture2D(src, srcCoords);"
" lowp float gray = dot(srcPixel.rgb, vec3(0.212671, 0.715160, 0.072169));"
" lowp vec3 colorized = 1.0-((1.0-gray)*(1.0-colorizeColor.rgb));"
" return vec4(mix(srcPixel.rgb, colorized * srcPixel.a, colorizeStrength), srcPixel.a);"
"}";
QGLPixmapColorizeFilter::QGLPixmapColorizeFilter()
{
setSource(qt_gl_colorize_filter);
}
bool QGLPixmapColorizeFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
{
QGLPixmapColorizeFilter *filter = const_cast<QGLPixmapColorizeFilter *>(this);
filter->setOnPainter(painter);
painter->drawPixmap(pos, src);
filter->removeFromPainter(painter);
return true;
}
void QGLPixmapColorizeFilter::setUniforms(QGLShaderProgram *program)
{
program->setUniformValue("colorizeColor", color());
program->setUniformValue("colorizeStrength", float(strength()));
}
void QGLPixmapConvolutionFilter::setUniforms(QGLShaderProgram *program)
{
const qreal *kernel = convolutionKernel();
int kernelWidth = columns();
int kernelHeight = rows();
int kernelSize = kernelWidth * kernelHeight;
QVarLengthArray<GLfloat> matrix(kernelSize);
QVarLengthArray<GLfloat> offset(kernelSize * 2);
for(int i = 0; i < kernelSize; ++i)
matrix[i] = kernel[i];
for(int y = 0; y < kernelHeight; ++y) {
for(int x = 0; x < kernelWidth; ++x) {
offset[(y * kernelWidth + x) * 2] = x - (kernelWidth / 2);
offset[(y * kernelWidth + x) * 2 + 1] = (kernelHeight / 2) - y;
}
}
const qreal iw = 1.0 / m_srcSize.width();
const qreal ih = 1.0 / m_srcSize.height();
program->setUniformValue("inv_texture_size", iw, ih);
program->setUniformValueArray("matrix", matrix.constData(), kernelSize, 1);
program->setUniformValueArray("offset", offset.constData(), kernelSize, 2);
}
// generates convolution filter code for arbitrary sized kernel
QByteArray QGLPixmapConvolutionFilter::generateConvolutionShader() const {
QByteArray code;
int kernelWidth = columns();
int kernelHeight = rows();
int kernelSize = kernelWidth * kernelHeight;
code.append("uniform highp vec2 inv_texture_size;\n"
"uniform mediump float matrix[");
code.append(QByteArray::number(kernelSize));
code.append("];\n"
"uniform highp vec2 offset[");
code.append(QByteArray::number(kernelSize));
code.append("];\n");
code.append("lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {\n");
code.append(" int i = 0;\n"
" lowp vec4 sum = vec4(0.0);\n"
" for (i = 0; i < ");
code.append(QByteArray::number(kernelSize));
code.append("; i++) {\n"
" sum += matrix[i] * texture2D(src,srcCoords+inv_texture_size*offset[i]);\n"
" }\n"
" return sum;\n"
"}");
return code;
}
QGLPixmapConvolutionFilter::QGLPixmapConvolutionFilter()
: m_prevKernelSize(-1)
{
}
QGLPixmapConvolutionFilter::~QGLPixmapConvolutionFilter()
{
}
bool QGLPixmapConvolutionFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
{
QGLPixmapConvolutionFilter *filter = const_cast<QGLPixmapConvolutionFilter *>(this);
m_srcSize = src.size();
int kernelSize = rows() * columns();
if (m_prevKernelSize == -1 || m_prevKernelSize != kernelSize) {
filter->setSource(generateConvolutionShader());
m_prevKernelSize = kernelSize;
}
filter->setOnPainter(painter);
painter->drawPixmap(pos, src, srcRect);
filter->removeFromPainter(painter);
return true;
}
QGLPixmapBlurFilter::QGLPixmapBlurFilter()
{
}
class QGLBlurTextureInfo
{
public:
QGLBlurTextureInfo(const QImage &image, GLuint tex, qreal r)
: m_texture(tex)
, m_radius(r)
{
m_paddedImage << image;
}
~QGLBlurTextureInfo()
{
glDeleteTextures(1, &m_texture);
}
QImage paddedImage(int scaleLevel = 0) const;
GLuint texture() const { return m_texture; }
qreal radius() const { return m_radius; }
private:
mutable QList<QImage> m_paddedImage;
GLuint m_texture;
qreal m_radius;
};
QImage QGLBlurTextureInfo::paddedImage(int scaleLevel) const
{
for (int i = m_paddedImage.size() - 1; i <= scaleLevel; ++i)
m_paddedImage << qt_halfScaled(m_paddedImage.at(i));
return m_paddedImage.at(scaleLevel);
}
class QGLBlurTextureCache : public QObject
{
public:
static QGLBlurTextureCache *cacheForContext(const QGLContext *context);
QGLBlurTextureCache(const QGLContext *);
~QGLBlurTextureCache();
QGLBlurTextureInfo *takeBlurTextureInfo(const QPixmap &pixmap);
bool hasBlurTextureInfo(quint64 cacheKey) const;
void insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info);
void clearBlurTextureInfo(quint64 cacheKey);
void timerEvent(QTimerEvent *event);
private:
static void pixmapDestroyed(QPlatformPixmap *pixmap);
QCache<quint64, QGLBlurTextureInfo > cache;
static QList<QGLBlurTextureCache *> blurTextureCaches;
int timerId;
};
QList<QGLBlurTextureCache *> QGLBlurTextureCache::blurTextureCaches;
Q_GLOBAL_STATIC(QGLContextGroupResource<QGLBlurTextureCache>, qt_blur_texture_caches)
QGLBlurTextureCache::QGLBlurTextureCache(const QGLContext *)
: timerId(0)
{
cache.setMaxCost(4 * 1024 * 1024);
blurTextureCaches.append(this);
}
QGLBlurTextureCache::~QGLBlurTextureCache()
{
blurTextureCaches.removeAt(blurTextureCaches.indexOf(this));
}
void QGLBlurTextureCache::timerEvent(QTimerEvent *)
{
killTimer(timerId);
timerId = 0;
cache.clear();
}
QGLBlurTextureCache *QGLBlurTextureCache::cacheForContext(const QGLContext *context)
{
return qt_blur_texture_caches()->value(context);
}
QGLBlurTextureInfo *QGLBlurTextureCache::takeBlurTextureInfo(const QPixmap &pixmap)
{
return cache.take(pixmap.cacheKey());
}
void QGLBlurTextureCache::clearBlurTextureInfo(quint64 cacheKey)
{
cache.remove(cacheKey);
}
bool QGLBlurTextureCache::hasBlurTextureInfo(quint64 cacheKey) const
{
return cache.contains(cacheKey);
}
void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info)
{
static bool hookAdded = false;
if (!hookAdded) {
QImagePixmapCleanupHooks::instance()->addPlatformPixmapDestructionHook(pixmapDestroyed);
QImagePixmapCleanupHooks::instance()->addPlatformPixmapModificationHook(pixmapDestroyed);
hookAdded = true;
}
QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
cache.insert(pixmap.cacheKey(), info, pixmap.width() * pixmap.height());
if (timerId)
killTimer(timerId);
timerId = startTimer(8000);
}
void QGLBlurTextureCache::pixmapDestroyed(QPlatformPixmap *pmd)
{
foreach (QGLBlurTextureCache *cache, blurTextureCaches) {
if (cache->hasBlurTextureInfo(pmd->cacheKey()))
cache->clearBlurTextureInfo(pmd->cacheKey());
}
}
static const int qAnimatedBlurLevelIncrement = 16;
static const int qMaxBlurHalfScaleLevel = 1;
static GLuint generateBlurTexture(const QSize &size, GLenum format = GL_RGBA)
{
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format,
GL_UNSIGNED_BYTE, 0);
return texture;
}
static inline uint nextMultiple(uint x, uint multiplier)
{
uint mod = x % multiplier;
if (mod == 0)
return x;
return x + multiplier - mod;
}
Q_GUI_EXPORT void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
quint32 *dest, int dstStride);
bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
{
if (radius() < 1) {
painter->drawPixmap(pos, src);
return true;
}
qreal actualRadius = radius();
QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
QGLBlurTextureInfo *info = 0;
int padding = nextMultiple(qCeil(actualRadius), qAnimatedBlurLevelIncrement);
QRect targetRect = src.rect().adjusted(-padding, -padding, padding, padding);
// pad so that we'll be able to half-scale qMaxBlurHalfScaleLevel times
targetRect.setWidth((targetRect.width() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));
targetRect.setHeight((targetRect.height() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));
QSize textureSize;
info = blurTextureCache->takeBlurTextureInfo(src);
if (!info || info->radius() < actualRadius) {
QSize paddedSize = targetRect.size() / 2;
QImage padded(paddedSize.height(), paddedSize.width(), QImage::Format_ARGB32_Premultiplied);
padded.fill(0);
if (info) {
int oldPadding = qRound(info->radius());
QPainter p(&padded);
p.setCompositionMode(QPainter::CompositionMode_Source);
p.drawImage((padding - oldPadding) / 2, (padding - oldPadding) / 2, info->paddedImage());
p.end();
} else {
// TODO: combine byteswapping and memrotating into one by declaring
// custom GL_RGBA pixel type and qt_colorConvert template for it
QImage prepadded = qt_halfScaled(src.toImage()).convertToFormat(QImage::Format_ARGB32_Premultiplied);
// byte-swap and memrotates in one go
qt_memrotate90_gl(reinterpret_cast<const quint32*>(prepadded.bits()),
prepadded.width(), prepadded.height(), prepadded.bytesPerLine(),
reinterpret_cast<quint32*>(padded.scanLine(padding / 2)) + padding / 2,
padded.bytesPerLine());
}
delete info;
info = new QGLBlurTextureInfo(padded, generateBlurTexture(paddedSize), padding);
textureSize = paddedSize;
} else {
textureSize = QSize(info->paddedImage().height(), info->paddedImage().width());
}
actualRadius *= qreal(0.5);
int level = 1;
for (; level < qMaxBlurHalfScaleLevel; ++level) {
if (actualRadius <= 16)
break;
actualRadius *= qreal(0.5);
}
const int s = (1 << level);
int prepadding = qRound(info->radius());
padding = qMin(prepadding, qCeil(actualRadius) << level);
targetRect = src.rect().adjusted(-padding, -padding, padding, padding);
targetRect.setWidth(targetRect.width() & ~(s-1));
targetRect.setHeight(targetRect.height() & ~(s-1));
int paddingDelta = (prepadding - padding) >> level;
QRect subRect(paddingDelta, paddingDelta, targetRect.width() >> level, targetRect.height() >> level);
QImage sourceImage = info->paddedImage(level-1);
QImage subImage(subRect.height(), subRect.width(), QImage::Format_ARGB32_Premultiplied);
qt_rectcopy((QRgb *)subImage.bits(), ((QRgb *)sourceImage.scanLine(paddingDelta)) + paddingDelta,
0, 0, subRect.height(), subRect.width(), subImage.bytesPerLine(), sourceImage.bytesPerLine());
GLuint texture = info->texture();
qt_blurImage(subImage, actualRadius, blurHints() & QGraphicsBlurEffect::QualityHint, 1);
// subtract one pixel off the end to prevent the bilinear sampling from sampling uninitialized data
QRect textureSubRect = subImage.rect().adjusted(0, 0, -1, -1);
QRectF targetRectF = QRectF(targetRect).adjusted(0, 0, -targetRect.width() / qreal(textureSize.width()), -targetRect.height() / qreal(textureSize.height()));
glBindTexture(GL_TEXTURE_2D, texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subImage.width(), subImage.height(), GL_RGBA,
GL_UNSIGNED_BYTE, const_cast<const QImage &>(subImage).bits());
QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
painter->setRenderHint(QPainter::SmoothPixmapTransform);
// texture is flipped on the y-axis
targetRectF = QRectF(targetRectF.x(), targetRectF.bottom(), targetRectF.width(), -targetRectF.height());
engine->drawTexture(targetRectF.translated(pos), texture, textureSize, textureSubRect);
blurTextureCache->insertBlurTextureInfo(src, info);
return true;
}
static const char *qt_gl_drop_shadow_filter =
"uniform lowp vec4 shadowColor;"
"lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
"{"
" return shadowColor * texture2D(src, srcCoords.yx).a;"
"}";
QGLPixmapDropShadowFilter::QGLPixmapDropShadowFilter()
{
setSource(qt_gl_drop_shadow_filter);
}
bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
{
QGLPixmapDropShadowFilter *filter = const_cast<QGLPixmapDropShadowFilter *>(this);
qreal r = blurRadius();
QRectF targetRectUnaligned = QRectF(src.rect()).translated(pos + offset()).adjusted(-r, -r, r, r);
QRect targetRect = targetRectUnaligned.toAlignedRect();
// ensure even dimensions (going to divide by two)
targetRect.setWidth((targetRect.width() + 1) & ~1);
targetRect.setHeight((targetRect.height() + 1) & ~1);
QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
QGLBlurTextureInfo *info = blurTextureCache->takeBlurTextureInfo(src);
if (!info || info->radius() != r) {
QImage half = qt_halfScaled(src.toImage().alphaChannel());
qreal rx = r + targetRect.left() - targetRectUnaligned.left();
qreal ry = r + targetRect.top() - targetRectUnaligned.top();
QImage image = QImage(targetRect.size() / 2, QImage::Format_Indexed8);
image.setColorTable(half.colorTable());
image.fill(0);
int dx = qRound(rx * qreal(0.5));
int dy = qRound(ry * qreal(0.5));
qt_rectcopy(image.bits(), half.bits(), dx, dy,
half.width(), half.height(),
image.bytesPerLine(), half.bytesPerLine());
qt_blurImage(image, r * qreal(0.5), false, 1);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, image.width(), image.height(),
0, GL_ALPHA, GL_UNSIGNED_BYTE, image.bits());
info = new QGLBlurTextureInfo(image, texture, r);
}
GLuint texture = info->texture();
filter->setOnPainter(painter);
QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
painter->setRenderHint(QPainter::SmoothPixmapTransform);
engine->drawTexture(targetRect, texture, info->paddedImage().size(), info->paddedImage().rect());
filter->removeFromPainter(painter);
// Now draw the actual pixmap over the top.
painter->drawPixmap(pos, src, srcRect);
blurTextureCache->insertBlurTextureInfo(src, info);
return true;
}
void QGLPixmapDropShadowFilter::setUniforms(QGLShaderProgram *program)
{
QColor col = color();
qreal alpha = col.alphaF();
program->setUniformValue("shadowColor", col.redF() * alpha,
col.greenF() * alpha,
col.blueF() * alpha,
alpha);
}
QT_END_NAMESPACE

View File

@ -1,94 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QGLPIXMAPFILTER_P_H
#define QGLPIXMAPFILTER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <private/qpixmapfilter_p.h>
#include <QtOpenGL/qgl.h>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QGLPixelBuffer;
QT_MODULE(OpenGL)
class QGLPixmapFilterBase
{
public:
virtual ~QGLPixmapFilterBase() {}
protected:
void bindTexture(const QPixmap &src) const;
void drawImpl(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
virtual bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const = 0;
};
template <typename Filter>
class QGLPixmapFilter : public Filter, public QGLPixmapFilterBase
{
public:
void draw(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect = QRectF()) const {
const QRectF source = srcRect.isNull() ? QRectF(src.rect()) : srcRect;
if (painter)
drawImpl(painter, pos, src, source);
}
};
QT_END_NAMESPACE
QT_END_HEADER
#endif // QGLPIXMAPFILTER_P_H

View File

@ -50,8 +50,6 @@
QT_BEGIN_NAMESPACE
#if !defined(QT_OPENGL_ES_1)
/*!
\class QGLShaderProgram
\brief The QGLShaderProgram class allows OpenGL shader programs to be linked and used.
@ -3269,86 +3267,4 @@ bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context)
return true;
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLShaderProgram::setAttributeArray
(int location, QMacCompatGLenum type, const void *values, int tupleSize, int stride)
{
setAttributeArray(location, GLenum(type), values, tupleSize, stride);
}
/*! \internal */
void QGLShaderProgram::setAttributeArray
(const char *name, QMacCompatGLenum type, const void *values, int tupleSize, int stride)
{
setAttributeArray(name, GLenum(type), values, tupleSize, stride);
}
/*! \internal */
void QGLShaderProgram::setAttributeBuffer
(int location, QMacCompatGLenum type, int offset, int tupleSize, int stride)
{
setAttributeBuffer(location, GLenum(type), offset, tupleSize, stride);
}
/*! \internal */
void QGLShaderProgram::setAttributeBuffer
(const char *name, QMacCompatGLenum type, int offset, int tupleSize, int stride)
{
setAttributeBuffer(name, GLenum(type), offset, tupleSize, stride);
}
/*! \internal */
void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value)
{
setUniformValue(location, GLint(value));
}
/*! \internal */
void QGLShaderProgram::setUniformValue(int location, QMacCompatGLuint value)
{
setUniformValue(location, GLuint(value));
}
/*! \internal */
void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLint value)
{
setUniformValue(name, GLint(value));
}
/*! \internal */
void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLuint value)
{
setUniformValue(name, GLuint(value));
}
/*! \internal */
void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLint *values, int count)
{
setUniformValueArray(location, (const GLint *)values, count);
}
/*! \internal */
void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLuint *values, int count)
{
setUniformValueArray(location, (const GLuint *)values, count);
}
/*! \internal */
void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLint *values, int count)
{
setUniformValueArray(name, (const GLint *)values, count);
}
/*! \internal */
void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count)
{
setUniformValueArray(name, (const GLuint *)values, count);
}
#endif
#endif // !defined(QT_OPENGL_ES_1)
QT_END_NAMESPACE

View File

@ -54,8 +54,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(OpenGL)
#if !defined(QT_OPENGL_ES_1)
class QGLShaderProgram;
class QGLShaderPrivate;
@ -204,17 +202,6 @@ public:
void setAttributeBuffer
(const char *name, GLenum type, int offset, int tupleSize, int stride = 0);
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
void setAttributeArray
(int location, QMacCompatGLenum type, const void *values, int tupleSize, int stride = 0);
void setAttributeArray
(const char *name, QMacCompatGLenum type, const void *values, int tupleSize, int stride = 0);
void setAttributeBuffer
(int location, QMacCompatGLenum type, int offset, int tupleSize, int stride = 0);
void setAttributeBuffer
(const char *name, QMacCompatGLenum type, int offset, int tupleSize, int stride = 0);
#endif
void enableAttributeArray(int location);
void enableAttributeArray(const char *name);
void disableAttributeArray(int location);
@ -224,17 +211,6 @@ public:
int uniformLocation(const QByteArray& name) const;
int uniformLocation(const QString& name) const;
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
void setUniformValue(int location, QMacCompatGLint value);
void setUniformValue(int location, QMacCompatGLuint value);
void setUniformValue(const char *name, QMacCompatGLint value);
void setUniformValue(const char *name, QMacCompatGLuint value);
void setUniformValueArray(int location, const QMacCompatGLint *values, int count);
void setUniformValueArray(int location, const QMacCompatGLuint *values, int count);
void setUniformValueArray(const char *name, const QMacCompatGLint *values, int count);
void setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count);
#endif
void setUniformValue(int location, GLfloat value);
void setUniformValue(int location, GLint value);
void setUniformValue(int location, GLuint value);
@ -335,8 +311,6 @@ private:
bool init();
};
#endif
QT_END_NAMESPACE
QT_END_HEADER

View File

@ -40,11 +40,9 @@
****************************************************************************/
#include "qgraphicsshadereffect_p.h"
#if !defined(QT_OPENGL_ES_1)
#include "qglshaderprogram.h"
#include "gl2paintengineex/qglcustomshaderstage_p.h"
#define QGL_HAVE_CUSTOM_SHADERS 1
#endif
#include <QtGui/qpainter.h>
#include <QtWidgets/qgraphicsitem.h>
#include <private/qgraphicseffect_p.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,158 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPAINTENGINE_OPENGL_P_H
#define QPAINTENGINE_OPENGL_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of the QLibrary class. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include <private/qpaintengineex_p.h>
QT_BEGIN_NAMESPACE
class QOpenGLPaintEnginePrivate;
class QGLTexture;
class QOpenGLPaintEngineState : public QPainterState
{
public:
QOpenGLPaintEngineState(QOpenGLPaintEngineState &other);
QOpenGLPaintEngineState();
~QOpenGLPaintEngineState();
QRegion clipRegion;
bool hasClipping;
QRect fastClip;
uint depthClipId;
};
class QOpenGLPaintEngine : public QPaintEngineEx
{
Q_DECLARE_PRIVATE(QOpenGLPaintEngine)
public:
QOpenGLPaintEngine();
~QOpenGLPaintEngine();
bool begin(QPaintDevice *pdev);
bool end();
// new stuff
void clipEnabledChanged();
void penChanged();
void brushChanged();
void brushOriginChanged();
void opacityChanged();
void compositionModeChanged();
void renderHintsChanged();
void transformChanged();
void fill(const QVectorPath &path, const QBrush &brush);
void clip(const QVectorPath &path, Qt::ClipOperation op);
void setState(QPainterState *s);
QPainterState *createState(QPainterState *orig) const;
inline QOpenGLPaintEngineState *state() {
return static_cast<QOpenGLPaintEngineState *>(QPaintEngineEx::state());
}
inline const QOpenGLPaintEngineState *state() const {
return static_cast<const QOpenGLPaintEngineState *>(QPaintEngineEx::state());
}
// old stuff
void updateState(const QPaintEngineState &state);
void updatePen(const QPen &pen);
void updateBrush(const QBrush &brush, const QPointF &pt);
void updateFont(const QFont &font);
void updateMatrix(const QTransform &matrix);
void updateClipRegion(const QRegion &region, Qt::ClipOperation op);
void updateRenderHints(QPainter::RenderHints hints);
void updateCompositionMode(QPainter::CompositionMode composition_mode);
void drawRects(const QRectF *r, int rectCount);
void drawLines(const QLineF *lines, int lineCount);
void drawPoints(const QPointF *p, int pointCount);
void drawRects(const QRect *r, int rectCount);
void drawLines(const QLine *lines, int lineCount);
void drawPoints(const QPoint *p, int pointCount);
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
void drawPath(const QPainterPath &path);
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
void drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
Qt::ImageConversionFlags conversionFlags);
void drawTextItem(const QPointF &p, const QTextItem &ti);
void drawStaticTextItem(QStaticTextItem *staticTextItem);
void drawEllipse(const QRectF &rect);
#ifdef Q_WS_WIN
HDC handle() const;
#else
Qt::HANDLE handle() const;
#endif
inline Type type() const { return QPaintEngine::OpenGL; }
bool supportsTransformations(qreal, const QTransform &) const { return true; }
private:
void drawPolyInternal(const QPolygonF &pa, bool close = true);
void drawTextureRect(int tx_width, int tx_height, const QRectF &r, const QRectF &sr,
GLenum target, QGLTexture *tex);
Q_DISABLE_COPY(QOpenGLPaintEngine)
};
QT_END_NAMESPACE
#endif // QPAINTENGINE_OPENGL_P_H