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:
parent
06f6b71ba4
commit
0d5170256c
93
configure
vendored
93
configure
vendored
@ -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
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
@ -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)
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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 |
@ -1,5 +0,0 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>qt.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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 ®ion)
|
||||
{
|
||||
if (!valid || !eglContext)
|
||||
return;
|
||||
|
||||
eglContext->swapBuffersRegion2NOK(eglSurfaceForDevice(), ®ion);
|
||||
}
|
||||
|
||||
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
|
@ -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
|
@ -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, ®ionBounds);
|
||||
Rect regionBoundsDest = regionBounds;
|
||||
regionBoundsDest.bottom *= scale;
|
||||
regionBoundsDest.right *= scale;
|
||||
MapRgn(region, ®ionBounds, ®ionBoundsDest);
|
||||
}
|
||||
|
||||
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
|
@ -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 ®ion);
|
||||
|
||||
#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
@ -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
@ -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
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
@ -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 ®ion, 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
|
Loading…
Reference in New Issue
Block a user