summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-10-05 01:44:20 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-10-05 01:44:20 (GMT)
commitc2dd4131e4eddd7669b2947e0bdd4ebae9cb26db (patch)
treeebd82aec99f15c14e689f15711c0a1e7267929d8
parenta7bf1cfb1a75c35e837c01f4a5b0697fc8961148 (diff)
parent2ab99337faa0ec03721fb39cae52361f7ac4d780 (diff)
downloadQt-c2dd4131e4eddd7669b2947e0bdd4ebae9cb26db.zip
Qt-c2dd4131e4eddd7669b2947e0bdd4ebae9cb26db.tar.gz
Qt-c2dd4131e4eddd7669b2947e0bdd4ebae9cb26db.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-s60-public into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-s60-public: Fix gcc compilation problems in QtOpenGL. Actually was typo and Revert "When using complex transformations rendering goes easily off by one pixel." fix for USER: 163 panic found on 5800XM Fixed library ordering when linking to qtmain. Made javascriptcore depend on corelib. Enable QtOpenGL vector path caching on Symbian/IVE3 Made scripttools disabled on Symbian by default, like on Windows. Got rid of "No such directory" warning when shadow building. Added qmake check for presence of RHttpDownloadMgr header Fixed crash on startup in Symbian debug build fixed hybrid heap Symbian udeb build issues qmediaplayer: show buffer status of 0% Progressive download in Phonon MMF backend: integrated with player Progressive download in Phonon MMF backend: added download managers Remove partial upgrade deployment generation for Webkit
-rwxr-xr-xconfigure14
-rw-r--r--demos/qmediaplayer/mediaplayer.cpp2
-rw-r--r--mkspecs/features/symbian/symbian_building.prf9
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.cpp170
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.h22
-rw-r--r--src/3rdparty/phonon/mmf/abstractvideoplayer.cpp24
-rw-r--r--src/3rdparty/phonon/mmf/abstractvideoplayer.h5
-rw-r--r--src/3rdparty/phonon/mmf/audioplayer.cpp18
-rw-r--r--src/3rdparty/phonon/mmf/audioplayer.h5
-rw-r--r--src/3rdparty/phonon/mmf/download.cpp194
-rw-r--r--src/3rdparty/phonon/mmf/download.h109
-rw-r--r--src/3rdparty/phonon/mmf/mediaobject.cpp36
-rw-r--r--src/3rdparty/phonon/mmf/mediaobject.h1
-rw-r--r--src/corelib/arch/symbian/debugfunction.cpp4
-rw-r--r--src/corelib/arch/symbian/heap_hybrid_p.h6
-rw-r--r--src/corelib/arch/symbian/qt_hybridheap_symbian_p.h5
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp42
-rw-r--r--src/opengl/gl2paintengineex/qtriangulator.cpp350
-rw-r--r--src/opengl/gl2paintengineex/qtriangulator_p.h58
-rw-r--r--src/opengl/qglextensions_p.h14
-rw-r--r--src/openvg/qpaintengine_vg.cpp158
-rw-r--r--src/plugins/phonon/mmf/mmf.pro50
-rw-r--r--src/qbase.pri31
-rw-r--r--src/src.pro5
-rw-r--r--tests/auto/qglthreads/tst_qglthreads.cpp5
25 files changed, 1024 insertions, 313 deletions
diff --git a/configure b/configure
index 53f520a..aca3467 100755
--- a/configure
+++ b/configure
@@ -4902,9 +4902,8 @@ case "$XPLATFORM" in *symbian*)
# Raptor does not support configure tests.
# the main commands needed to compile;
- (cd config.tests/symbian
- mkdir -p rcomp
- cd rcomp
+ (mkdir -p config.tests/symbian/rcomp
+ cd config.tests/symbian/rcomp
rm -f rcomp_test.rsg
touch rcomp_test.rpp rcomp_test.rsc rcomp_test.rss
rcomp -u -m045,046,047 -s./rcomp_test.rpp -o./rcomp_test.rsc -h./rcomp_test.rsg -i./rcomp_test.rss 2>&1 > /dev/null
@@ -7225,7 +7224,14 @@ if [ "$CFG_SCRIPTTOOLS" = "yes" -a "$CFG_SCRIPT" = "no" ]; then
exit 1
fi
if [ "$CFG_SCRIPTTOOLS" = "auto" -a "$CFG_SCRIPT" != "no" ]; then
- CFG_SCRIPTTOOLS="yes"
+ case "$XPLATFORM" in
+ symbian*)
+ CFG_SCRIPTTOOLS="no"
+ ;;
+ *)
+ CFG_SCRIPTTOOLS="yes"
+ ;;
+ esac
elif [ "$CFG_SCRIPT" = "no" ]; then
CFG_SCRIPTTOOLS="no"
fi
diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp
index 3cb0616..97a8e35 100644
--- a/demos/qmediaplayer/mediaplayer.cpp
+++ b/demos/qmediaplayer/mediaplayer.cpp
@@ -716,7 +716,7 @@ void MediaPlayer::openFile()
void MediaPlayer::bufferStatus(int percent)
{
- if (percent == 0 || percent == 100)
+ if (percent == 100)
progressLabel->setText(QString());
else {
QString str = QString::fromLatin1("(%1%)").arg(percent);
diff --git a/mkspecs/features/symbian/symbian_building.prf b/mkspecs/features/symbian/symbian_building.prf
index 539609d..614fb65 100644
--- a/mkspecs/features/symbian/symbian_building.prf
+++ b/mkspecs/features/symbian/symbian_building.prf
@@ -187,9 +187,11 @@ contains(TEMPLATE, app):!contains(QMAKE_LINK, "^@:.*") {
linux-armcc: {
QMAKE_LIBS += usrt2_2.lib dfpaeabi.dso dfprvct2_2.dso drtaeabi.dso scppnwdl.dso drtrvct2_2.dso h_t__uf.l\\(switch8.o\\)
QMAKE_LIBS += -leexe.lib\\(uc_exe_.o\\)
- contains(CONFIG, "qt"):contains(QT, "core") { #if linking with QtCore
+ contains(CONFIG, "qt"):contains(QT, "gui") { #if linking with QtCore
+ QMAKE_LIBS -= -lqtmain$${QT_LIBINFIX}.lib
QMAKE_LIBS += -lqtmain$${QT_LIBINFIX}.lib
} else {
+ QMAKE_LIBS -= -llibcrt0.lib
QMAKE_LIBS += -llibcrt0.lib
}
} else :linux-gcce {
@@ -197,9 +199,12 @@ contains(TEMPLATE, app):!contains(QMAKE_LINK, "^@:.*") {
QMAKE_LIBS += \
-l:eexe.lib \
-l:usrt2_2.lib
- contains(CONFIG, "qt"):contains(QT, "core") { #if linking with QtCore
+ contains(CONFIG, "qt"):contains(QT, "gui") { #if linking with QtCore
+ QMAKE_LIBS -= -l:qtmain$${QT_LIBINFIX}.lib
QMAKE_LIBS += -l:qtmain$${QT_LIBINFIX}.lib
} else {
+ QMAKE_LIBS -= -l:libcrt0.lib
+ QMAKE_LIBS -= -l:libcrt0_gcce.lib
QMAKE_LIBS += -l:libcrt0_gcce.lib
}
QMAKE_LIBS += \
diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
index 3702560..dfc5840 100644
--- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
+++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
@@ -51,10 +51,15 @@ MMF::AbstractMediaPlayer::AbstractMediaPlayer
, m_parent(parent)
, m_pending(NothingPending)
, m_positionTimer(new QTimer(this))
+ , m_position(0)
, m_bufferStatusTimer(new QTimer(this))
, m_mmfMaxVolume(NullMaxVolume)
, m_prefinishMarkSent(false)
, m_aboutToFinishSent(false)
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ , m_download(0)
+ , m_downloadStalled(false)
+#endif
{
connect(m_positionTimer.data(), SIGNAL(timeout()), this, SLOT(positionTick()));
connect(m_bufferStatusTimer.data(), SIGNAL(timeout()), this, SLOT(bufferStatusTick()));
@@ -183,6 +188,7 @@ void MMF::AbstractMediaPlayer::seek(qint64 ms)
}
doSeek(ms);
+ m_position = ms;
resetMarksIfRewound();
if(wasPlaying && state() != ErrorState) {
@@ -207,6 +213,11 @@ bool MMF::AbstractMediaPlayer::isSeekable() const
return true;
}
+qint64 MMF::AbstractMediaPlayer::currentTime() const
+{
+ return m_position;
+}
+
void MMF::AbstractMediaPlayer::doSetTickInterval(qint32 interval)
{
TRACE_CONTEXT(AbstractMediaPlayer::doSetTickInterval, EAudioApi);
@@ -247,7 +258,19 @@ void MMF::AbstractMediaPlayer::open()
symbianErr = openFile(*file);
if (KErrNone != symbianErr)
errorMessage = tr("Error opening file");
- } else {
+ }
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ else if (url.scheme() == QLatin1String("http")) {
+ Q_ASSERT(!m_download);
+ m_download = new Download(url, this);
+ connect(m_download, SIGNAL(lengthChanged(qint64)),
+ this, SLOT(downloadLengthChanged(qint64)));
+ connect(m_download, SIGNAL(stateChanged(Download::State)),
+ this, SLOT(downloadStateChanged(Download::State)));
+ m_download->start();
+ }
+#endif
+ else {
symbianErr = openUrl(url.toString());
if (KErrNone != symbianErr)
errorMessage = tr("Error opening URL");
@@ -288,6 +311,16 @@ void MMF::AbstractMediaPlayer::open()
TRACE_EXIT_0();
}
+void MMF::AbstractMediaPlayer::close()
+{
+ doClose();
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ delete m_download;
+ m_download = 0;
+#endif
+ m_position = 0;
+}
+
void MMF::AbstractMediaPlayer::volumeChanged(qreal volume)
{
TRACE_CONTEXT(AbstractMediaPlayer::volumeChanged, EAudioInternal);
@@ -374,7 +407,8 @@ void MMF::AbstractMediaPlayer::bufferingComplete()
{
stopBufferStatusTimer();
emit MMF::AbstractPlayer::bufferStatus(100);
- changeState(m_stateBeforeBuffering);
+ if (!progressiveDownloadStalled())
+ changeState(m_stateBeforeBuffering);
}
void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume)
@@ -385,13 +419,30 @@ void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume)
void MMF::AbstractMediaPlayer::loadingComplete(int error)
{
- Q_ASSERT(Phonon::LoadingState == state());
-
- if (KErrNone == error) {
- updateMetaData();
- changeState(StoppedState);
+ TRACE_CONTEXT(AbstractMediaPlayer::loadingComplete, EAudioApi);
+ TRACE_ENTRY("state %d error %d", state(), error);
+ if (progressiveDownloadStalled()) {
+ Q_ASSERT(Phonon::BufferingState == state());
+ if (KErrNone == error) {
+ bufferingComplete();
+ doSeek(m_position);
+ startPlayback();
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ m_downloadStalled = false;
+#endif
+ }
} else {
- setError(tr("Loading clip failed"), error);
+ Q_ASSERT(Phonon::LoadingState == state());
+ if (KErrNone == error) {
+ updateMetaData();
+ changeState(StoppedState);
+ } else {
+ if (isProgressiveDownload() && KErrCorrupt == error) {
+ setProgressiveDownloadStalled();
+ } else {
+ setError(tr("Loading clip failed"), error);
+ }
+ }
}
}
@@ -415,8 +466,12 @@ void MMF::AbstractMediaPlayer::playbackComplete(int error)
QMetaObject::invokeMethod(m_parent, "switchToNextSource", Qt::QueuedConnection);
}
else {
- setError(tr("Playback complete"), error);
- emit finished();
+ if (isProgressiveDownload() && KErrCorrupt == error) {
+ setProgressiveDownloadStalled();
+ } else {
+ setError(tr("Playback complete"), error);
+ emit finished();
+ }
}
}
@@ -425,15 +480,36 @@ qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds
return in.Int64() / 1000;
}
+bool MMF::AbstractMediaPlayer::isProgressiveDownload() const
+{
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ return (0 != m_download);
+#else
+ return false;
+#endif
+}
+
+bool MMF::AbstractMediaPlayer::progressiveDownloadStalled() const
+{
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ return m_downloadStalled;
+#else
+ return false;
+#endif
+}
+
//-----------------------------------------------------------------------------
// Slots
//-----------------------------------------------------------------------------
void MMF::AbstractMediaPlayer::positionTick()
{
- const qint64 current = currentTime();
- emitMarksIfReached(current);
- emit MMF::AbstractPlayer::tick(current);
+ const qint64 pos = getCurrentTime();
+ if (pos > m_position) {
+ m_position = pos;
+ emitMarksIfReached(m_position);
+ emit MMF::AbstractPlayer::tick(m_position);
+ }
}
void MMF::AbstractMediaPlayer::emitMarksIfReached(qint64 current)
@@ -458,7 +534,7 @@ void MMF::AbstractMediaPlayer::emitMarksIfReached(qint64 current)
void MMF::AbstractMediaPlayer::resetMarksIfRewound()
{
- const qint64 current = currentTime();
+ const qint64 current = getCurrentTime();
const qint64 total = totalTime();
const qint64 remaining = total - current;
@@ -487,10 +563,74 @@ void MMF::AbstractMediaPlayer::startPlayback()
changeState(PlayingState);
}
+void MMF::AbstractMediaPlayer::setProgressiveDownloadStalled()
+{
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ TRACE_CONTEXT(AbstractMediaPlayer::setProgressiveDownloadStalled, EAudioApi);
+ TRACE_ENTRY("state %d", state());
+ Q_ASSERT(isProgressiveDownload());
+ m_downloadStalled = true;
+ doClose();
+ bufferingStarted();
+ // Video player loses window handle when closed - need to reapply it here
+ videoOutputChanged();
+ m_download->resume();
+#endif
+}
+
void MMF::AbstractMediaPlayer::bufferStatusTick()
{
- emit MMF::AbstractPlayer::bufferStatus(bufferStatus());
+ // During progressive download, there is no way to detect the buffering status.
+ // Phonon does not support a "buffering; amount unknown" signal, therefore we
+ // return a buffering status of zero.
+ const int status = progressiveDownloadStalled() ? 0 : bufferStatus();
+ emit MMF::AbstractPlayer::bufferStatus(status);
+}
+
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+void MMF::AbstractMediaPlayer::downloadLengthChanged(qint64 length)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::downloadLengthChanged, EAudioApi);
+ TRACE_ENTRY("length %Ld", length);
+ Q_UNUSED(length)
+ if (m_downloadStalled) {
+ bufferingComplete();
+ int err = m_parent->openFileHandle(m_download->targetFileName());
+ if (KErrNone == err)
+ err = openFile(*m_parent->file());
+ if (KErrNone != err)
+ setError(tr("Error opening file"));
+ }
+}
+
+void MMF::AbstractMediaPlayer::downloadStateChanged(Download::State state)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::downloadStateChanged, EAudioApi);
+ TRACE_ENTRY("state %d", state);
+ switch (state) {
+ case Download::Idle:
+ case Download::Initializing:
+ break;
+ case Download::Downloading:
+ {
+ int err = m_parent->openFileHandle(m_download->targetFileName());
+ if (KErrNone == err)
+ err = openFile(*m_parent->file());
+ else if (KErrCorrupt == err)
+ // Insufficient data downloaded - enter Buffering state
+ setProgressiveDownloadStalled();
+ if (KErrNone != err)
+ setError(tr("Error opening file"));
+ }
+ break;
+ case Download::Complete:
+ break;
+ case Download::Error:
+ setError(tr("Download error"));
+ break;
+ }
}
+#endif // PHONON_MMF_PROGRESSIVE_DOWNLOAD
Phonon::State MMF::AbstractMediaPlayer::phononState(PrivateState state) const
{
diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h
index e795ecb..c3b4528 100644
--- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h
+++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h
@@ -23,6 +23,9 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <QScopedPointer>
#include <e32std.h>
#include "abstractplayer.h"
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+# include "download.h"
+#endif
class RFile;
@@ -48,6 +51,7 @@ protected:
public:
virtual void open();
+ virtual void close();
// MediaObjectInterface
virtual void play();
@@ -55,6 +59,7 @@ public:
virtual void stop();
virtual void seek(qint64 milliseconds);
virtual bool isSeekable() const;
+ virtual qint64 currentTime() const;
virtual void volumeChanged(qreal volume);
protected:
@@ -68,12 +73,15 @@ protected:
virtual void doStop() = 0;
virtual void doSeek(qint64 pos) = 0;
virtual int setDeviceVolume(int mmfVolume) = 0;
+ virtual int openFile(const QString &fileName) = 0;
virtual int openFile(RFile& file) = 0;
virtual int openUrl(const QString& url) = 0;
virtual int openDescriptor(const TDesC8 &des) = 0;
virtual int bufferStatus() const = 0;
+ virtual void doClose() = 0;
void updateMetaData();
+ virtual qint64 getCurrentTime() const = 0;
virtual int numberOfMetaDataEntries() const = 0;
virtual QPair<QString, QString> metaDataEntry(int index) const = 0;
@@ -86,6 +94,9 @@ protected:
static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &);
+ bool isProgressiveDownload() const;
+ bool progressiveDownloadStalled() const;
+
private:
void startPositionTimer();
void stopPositionTimer();
@@ -96,6 +107,7 @@ private:
void emitMarksIfReached(qint64 position);
void resetMarksIfRewound();
void startPlayback();
+ void setProgressiveDownloadStalled();
enum Pending {
NothingPending,
@@ -108,6 +120,10 @@ private:
private Q_SLOTS:
void positionTick();
void bufferStatusTick();
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ void downloadLengthChanged(qint64);
+ void downloadStateChanged(Download::State);
+#endif
private:
MediaObject *const m_parent;
@@ -115,6 +131,7 @@ private:
Pending m_pending;
QScopedPointer<QTimer> m_positionTimer;
+ qint64 m_position;
QScopedPointer<QTimer> m_bufferStatusTimer;
PrivateState m_stateBeforeBuffering;
@@ -127,6 +144,11 @@ private:
// Used for playback of resource files
TPtrC8 m_buffer;
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ Download *m_download;
+ bool m_downloadStalled;
+#endif
+
QMultiMap<QString, QString> m_metaData;
};
diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
index fb20bea..1ab5bae 100644
--- a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
+++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
@@ -16,6 +16,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <QDir>
#include <QUrl>
#include <QTimer>
#include <QWidget>
@@ -132,6 +133,13 @@ int MMF::AbstractVideoPlayer::setDeviceVolume(int mmfVolume)
return err;
}
+int MMF::AbstractVideoPlayer::openFile(const QString &fileName)
+{
+ const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
+ TRAPD(err, m_player->OpenFileL(*nativeFileName));
+ return err;
+}
+
int MMF::AbstractVideoPlayer::openFile(RFile &file)
{
TRAPD(err, m_player->OpenFileL(file));
@@ -157,7 +165,7 @@ int MMF::AbstractVideoPlayer::bufferStatus() const
return result;
}
-void MMF::AbstractVideoPlayer::close()
+void MMF::AbstractVideoPlayer::doClose()
{
m_player->Close();
}
@@ -167,9 +175,9 @@ bool MMF::AbstractVideoPlayer::hasVideo() const
return true;
}
-qint64 MMF::AbstractVideoPlayer::currentTime() const
+qint64 MMF::AbstractVideoPlayer::getCurrentTime() const
{
- TRACE_CONTEXT(AbstractVideoPlayer::currentTime, EVideoApi);
+ TRACE_CONTEXT(AbstractVideoPlayer::getCurrentTime, EVideoApi);
TTimeIntervalMicroSeconds us;
TRAPD(err, us = m_player->PositionL())
@@ -246,7 +254,9 @@ void MMF::AbstractVideoPlayer::MvpuoOpenComplete(TInt aError)
TRACE_CONTEXT(AbstractVideoPlayer::MvpuoOpenComplete, EVideoApi);
TRACE_ENTRY("state %d error %d", state(), aError);
- __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
+ __ASSERT_ALWAYS(LoadingState == state() ||
+ progressiveDownloadStalled() && BufferingState == state(),
+ Utils::panic(InvalidStatePanic));
if (KErrNone == aError)
m_player->Prepare();
@@ -261,7 +271,9 @@ void MMF::AbstractVideoPlayer::MvpuoPrepareComplete(TInt aError)
TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPrepareComplete, EVideoApi);
TRACE_ENTRY("state %d error %d", state(), aError);
- __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
+ __ASSERT_ALWAYS(LoadingState == state() ||
+ progressiveDownloadStalled() && BufferingState == state(),
+ Utils::panic(InvalidStatePanic));
TRAPD(err, getVideoClipParametersL(aError));
@@ -470,7 +482,7 @@ void MMF::AbstractVideoPlayer::updateScaleFactors(const QSize &windowSize, bool
void MMF::AbstractVideoPlayer::parametersChanged(VideoParameters parameters)
{
- if (state() == LoadingState)
+ if (state() == LoadingState || progressiveDownloadStalled() && BufferingState == state())
m_pendingChanges |= parameters;
else
handleParametersChanged(parameters);
diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.h b/src/3rdparty/phonon/mmf/abstractvideoplayer.h
index 3ff3c75..3bc5c7c 100644
--- a/src/3rdparty/phonon/mmf/abstractvideoplayer.h
+++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.h
@@ -64,21 +64,22 @@ public:
virtual void doStop();
virtual void doSeek(qint64 milliseconds);
virtual int setDeviceVolume(int mmfVolume);
+ virtual int openFile(const QString &fileName);
virtual int openFile(RFile &file);
virtual int openUrl(const QString &url);
virtual int openDescriptor(const TDesC8 &des);
virtual int bufferStatus() const;
- virtual void close();
+ virtual void doClose();
// MediaObjectInterface
virtual bool hasVideo() const;
- virtual qint64 currentTime() const;
virtual qint64 totalTime() const;
// AbstractPlayer
virtual void videoOutputChanged();
// AbstractMediaPlayer
+ virtual qint64 getCurrentTime() const;
virtual int numberOfMetaDataEntries() const;
virtual QPair<QString, QString> metaDataEntry(int index) const;
diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp
index 7c8b9bd..dc5c800 100644
--- a/src/3rdparty/phonon/mmf/audioplayer.cpp
+++ b/src/3rdparty/phonon/mmf/audioplayer.cpp
@@ -16,6 +16,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <QDir>
#include <QUrl>
#include "audioplayer.h"
@@ -109,6 +110,13 @@ int MMF::AudioPlayer::setDeviceVolume(int mmfVolume)
#endif
}
+int MMF::AudioPlayer::openFile(const QString &fileName)
+{
+ const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
+ TRAPD(err, m_player->OpenFileL(*nativeFileName));
+ return err;
+}
+
int MMF::AudioPlayer::openFile(RFile& file)
{
TRAPD(err, m_player->OpenFileL(file));
@@ -150,7 +158,7 @@ int MMF::AudioPlayer::bufferStatus() const
return result;
}
-void MMF::AudioPlayer::close()
+void MMF::AudioPlayer::doClose()
{
m_player->Close();
}
@@ -160,9 +168,9 @@ bool MMF::AudioPlayer::hasVideo() const
return false;
}
-qint64 MMF::AudioPlayer::currentTime() const
+qint64 MMF::AudioPlayer::getCurrentTime() const
{
- TRACE_CONTEXT(AudioPlayer::currentTime, EAudioApi);
+ TRACE_CONTEXT(AudioPlayer::getCurrentTime, EAudioApi);
TTimeIntervalMicroSeconds us;
const TInt err = m_player->GetPosition(us);
@@ -203,7 +211,9 @@ void MMF::AudioPlayer::MapcInitComplete(TInt aError,
TRACE_CONTEXT(AudioPlayer::MapcInitComplete, EAudioInternal);
TRACE_ENTRY("state %d error %d", state(), aError);
- __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
+ __ASSERT_ALWAYS(LoadingState == state() ||
+ progressiveDownloadStalled() && BufferingState == state(),
+ Utils::panic(InvalidStatePanic));
if (KErrNone == aError) {
maxVolumeChanged(m_player->MaxVolume());
diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h
index e43cadd..cf4f6d5 100644
--- a/src/3rdparty/phonon/mmf/audioplayer.h
+++ b/src/3rdparty/phonon/mmf/audioplayer.h
@@ -65,18 +65,19 @@ typedef CMdaAudioPlayerUtility NativePlayer;
virtual void doStop();
virtual void doSeek(qint64 milliseconds);
virtual int setDeviceVolume(int mmfVolume);
+ virtual int openFile(const QString &fileName);
virtual int openFile(RFile& file);
virtual int openUrl(const QString& url);
virtual int openDescriptor(const TDesC8 &des);
virtual int bufferStatus() const;
- virtual void close();
+ virtual void doClose();
// MediaObjectInterface
virtual bool hasVideo() const;
- virtual qint64 currentTime() const;
virtual qint64 totalTime() const;
// AbstractMediaPlayer
+ virtual qint64 getCurrentTime() const;
virtual int numberOfMetaDataEntries() const;
virtual QPair<QString, QString> metaDataEntry(int index) const;
diff --git a/src/3rdparty/phonon/mmf/download.cpp b/src/3rdparty/phonon/mmf/download.cpp
new file mode 100644
index 0000000..7b80e4a
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/download.cpp
@@ -0,0 +1,194 @@
+/* This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "download.h"
+#include "utils.h"
+#include <QtCore/QDir>
+#include <QtCore/private/qcore_symbian_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+static const TBool InheritDownloads = EFalse;
+
+DownloadPrivate::DownloadPrivate(Download *parent)
+ : QObject(parent)
+ , m_parent(parent)
+ , m_download(0)
+ , m_length(0)
+{
+
+}
+
+DownloadPrivate::~DownloadPrivate()
+{
+ m_downloadManager.Disconnect();
+ m_downloadManager.Close();
+}
+
+bool DownloadPrivate::start()
+{
+ TRACE_CONTEXT(DownloadPrivate::start, EVideoApi);
+ Q_ASSERT(!m_download);
+ // Connect to download manager
+ RProcess process;
+ const TUid uid3 = process.SecureId();
+ TRAPD(err, m_downloadManager.ConnectL(uid3, *this, InheritDownloads));
+ TRACE("connect err %d", err);
+ if (KErrNone == err) {
+ // Start download
+ QHBufC url(m_parent->sourceUrl().toString());
+ TPtr8 url8 = url->Des().Collapse();
+ TRAP(err, m_download = &m_downloadManager.CreateDownloadL(url8));
+ TRACE("start err %d", err);
+ if (KErrNone == err)
+ m_download->Start();
+ }
+ return (KErrNone == err);
+}
+
+void DownloadPrivate::resume()
+{
+
+}
+
+void DownloadPrivate::HandleDMgrEventL(RHttpDownload &aDownload, THttpDownloadEvent aEvent)
+{
+ TRACE_CONTEXT(DownloadPrivate::HandleDMgrEventL, EVideoApi);
+ Q_ASSERT(&aDownload == m_download);
+ switch (aEvent.iDownloadState) {
+ case EHttpDlPaused:
+ if (EHttpContentTypeReceived == aEvent.iProgressState) {
+ TRACE_0("paused, content type received");
+ m_download->Start();
+ }
+ break;
+ case EHttpDlInprogress:
+ switch (aEvent.iProgressState) {
+ case EHttpProgResponseHeaderReceived:
+ {
+ TFileName fileName;
+ m_download->GetStringAttribute(EDlAttrDestFilename, fileName);
+ TRACE("in progress, response header received, filename %S", &fileName);
+ const QString fileNameQt = QDir::fromNativeSeparators(qt_TDesC2QString(fileName));
+ m_parent->downloadStarted(fileNameQt);
+ }
+ break;
+ case EHttpProgResponseBodyReceived:
+ {
+ TInt32 length = 0;
+ m_download->GetIntAttribute(EDlAttrDownloadedSize, length);
+ if (length != m_length) {
+ TRACE("in progress, length %d", length);
+ m_length = length;
+ emit lengthChanged(m_length);
+ }
+ }
+ break;
+ }
+ break;
+ case EHttpDlCompleted:
+ TRACE_0("complete");
+ m_parent->complete();
+ break;
+ case EHttpDlFailed:
+ TRACE_0("failed");
+ m_parent->error();
+ break;
+ }
+}
+
+Download::Download(const QUrl &url, QObject *parent)
+ : QObject(parent)
+ , m_private(new DownloadPrivate(this))
+ , m_sourceUrl(url)
+ , m_state(Idle)
+{
+ qRegisterMetaType<Download::State>();
+ connect(m_private, SIGNAL(lengthChanged(qint64)), this, SIGNAL(lengthChanged(qint64)));
+}
+
+Download::~Download()
+{
+
+}
+
+const QUrl &Download::sourceUrl() const
+{
+ return m_sourceUrl;
+}
+
+const QString &Download::targetFileName() const
+{
+ return m_targetFileName;
+}
+
+void Download::start()
+{
+ TRACE_CONTEXT(Download::start, EVideoApi);
+ TRACE_ENTRY_0();
+ Q_ASSERT(Idle == m_state);
+ const bool ok = m_private->start();
+ setState(ok ? Initializing : Error);
+ TRACE_EXIT_0();
+}
+
+void Download::resume()
+{
+ TRACE_CONTEXT(Download::resume, EVideoApi);
+ TRACE_ENTRY_0();
+ m_private->resume();
+ TRACE_EXIT_0();
+}
+
+void Download::setState(State state)
+{
+ TRACE_CONTEXT(Download::setState, EVideoApi);
+ TRACE("oldState %d newState %d", m_state, state);
+ const State oldState = m_state;
+ m_state = state;
+ if (oldState != m_state)
+ emit stateChanged(m_state);
+}
+
+void Download::error()
+{
+ TRACE_CONTEXT(Download::error, EVideoApi);
+ TRACE_0("");
+ setState(Error);
+}
+
+void Download::downloadStarted(const QString &targetFileName)
+{
+ TRACE_CONTEXT(Download::downloadStarted, EVideoApi);
+ TRACE_0("downloadStarted");
+ m_targetFileName = targetFileName;
+ setState(Downloading);
+}
+
+void Download::complete()
+{
+ TRACE_CONTEXT(Download::complete, EVideoApi);
+ TRACE_0("");
+ setState(Complete);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/download.h b/src/3rdparty/phonon/mmf/download.h
new file mode 100644
index 0000000..bda7963
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/download.h
@@ -0,0 +1,109 @@
+/* This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef PHONON_MMF_DOWNLOAD_H
+#define PHONON_MMF_DOWNLOAD_H
+
+#include <QtCore/QMetaType>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+#include <downloadmgrclient.h>
+
+QT_FORWARD_DECLARE_CLASS(QByteArray)
+QT_FORWARD_DECLARE_CLASS(QFile)
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+class Download;
+
+class DownloadPrivate : public QObject
+ , public MHttpDownloadMgrObserver
+{
+ Q_OBJECT
+public:
+ DownloadPrivate(Download *parent);
+ ~DownloadPrivate();
+ bool start();
+ void resume();
+signals:
+ void error();
+ void targetFileNameChanged();
+ void lengthChanged(qint64 length);
+ void complete();
+private:
+ // MHttpDownloadMgrObserver
+ void HandleDMgrEventL(RHttpDownload &aDownload, THttpDownloadEvent aEvent);
+private:
+ Download *m_parent;
+ RHttpDownloadMgr m_downloadManager;
+ RHttpDownload *m_download;
+ qint64 m_length;
+};
+
+class Download : public QObject
+{
+ Q_OBJECT
+ friend class DownloadPrivate;
+public:
+ Download(const QUrl &url, QObject *parent = 0);
+ ~Download();
+ const QUrl &sourceUrl() const;
+ const QString &targetFileName() const;
+ void start();
+ void resume();
+
+ enum State {
+ Idle,
+ Initializing,
+ Downloading,
+ Complete,
+ Error
+ };
+
+signals:
+ void lengthChanged(qint64 length);
+ void stateChanged(Download::State state);
+
+private:
+ void setState(State state);
+
+ // Called by DownloadPrivate
+ void error();
+ void downloadStarted(const QString &targetFileName);
+ void complete();
+
+private:
+ DownloadPrivate *m_private;
+ QUrl m_sourceUrl;
+ QString m_targetFileName;
+ State m_state;
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(Phonon::MMF::Download::State)
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp
index 98326b8..2c7a7ef 100644
--- a/src/3rdparty/phonon/mmf/mediaobject.cpp
+++ b/src/3rdparty/phonon/mmf/mediaobject.cpp
@@ -61,6 +61,9 @@ MMF::MediaObject::MediaObject(QObject *parent) : MMF::MediaNode::MediaNode(paren
TRACE_CONTEXT(MediaObject::MediaObject, EAudioApi);
TRACE_ENTRY_0();
+ const int err = m_fileServer.Connect();
+ QT_TRAP_THROWING(User::LeaveIfError(err));
+
Q_UNUSED(parent);
TRACE_EXIT_0();
@@ -99,12 +102,6 @@ bool MMF::MediaObject::openRecognizer()
return false;
}
- err = m_fileServer.Connect();
- if (KErrNone != err) {
- TRACE("RFs::Connect error %d", err);
- return false;
- }
-
// This must be called in order to be able to share file handles with
// the recognizer server (see fileMediaType function).
err = m_fileServer.ShareProtected();
@@ -127,13 +124,8 @@ MMF::MediaType MMF::MediaObject::fileMediaType
MediaType result = MediaTypeUnknown;
if (openRecognizer()) {
-
- const QHBufC fileNameSymbian(QDir::toNativeSeparators(fileName));
-
- Q_ASSERT(!m_file);
- m_file = new RFile;
- TInt err = m_file->Open(m_fileServer, *fileNameSymbian, EFileRead | EFileShareReadersOnly);
-
+ TInt err = openFileHandle(fileName);
+ const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
if (KErrNone == err) {
TDataRecognitionResult recognizerResult;
err = m_recognizer.RecognizeData(*m_file, recognizerResult);
@@ -141,16 +133,30 @@ MMF::MediaType MMF::MediaObject::fileMediaType
const TPtrC mimeType = recognizerResult.iDataType.Des();
result = Utils::mimeTypeToMediaType(mimeType);
} else {
- TRACE("RApaLsSession::RecognizeData filename %S error %d", fileNameSymbian.data(), err);
+ TRACE("RApaLsSession::RecognizeData filename %S error %d", nativeFileName.data(), err);
}
} else {
- TRACE("RFile::Open filename %S error %d", fileNameSymbian.data(), err);
+ TRACE("RFile::Open filename %S error %d", nativeFileName.data(), err);
}
}
return result;
}
+int MMF::MediaObject::openFileHandle(const QString &fileName)
+{
+ TRACE_CONTEXT(MediaObject::openFileHandle, EAudioInternal);
+ const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
+ TRACE_ENTRY("filename %S", nativeFileName.data());
+ if (m_file)
+ m_file->Close();
+ delete m_file;
+ m_file = 0;
+ m_file = new RFile;
+ TInt err = m_file->Open(m_fileServer, *nativeFileName, EFileRead | EFileShareReadersOrWriters);
+ return err;
+}
+
MMF::MediaType MMF::MediaObject::bufferMediaType(const uchar *data, qint64 size)
{
TRACE_CONTEXT(MediaObject::bufferMediaType, EAudioInternal);
diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h
index 5399e27..5d785fb 100644
--- a/src/3rdparty/phonon/mmf/mediaobject.h
+++ b/src/3rdparty/phonon/mmf/mediaobject.h
@@ -89,6 +89,7 @@ public:
void setVideoOutput(AbstractVideoOutput* videoOutput);
+ int openFileHandle(const QString &fileName);
RFile* file() const;
QResource* resource() const;
diff --git a/src/corelib/arch/symbian/debugfunction.cpp b/src/corelib/arch/symbian/debugfunction.cpp
index f3b5d2d..31937e8 100644
--- a/src/corelib/arch/symbian/debugfunction.cpp
+++ b/src/corelib/arch/symbian/debugfunction.cpp
@@ -549,7 +549,7 @@ void ResetAllocCellLevels(TAny* aPtr, RHybridHeap::TCellType aType, TAny* aCell,
if (aType == RHybridHeap::EGoodAllocatedCell)
{
- RHybridHeap::SDebugCell* DbgCell = (RHybridHeap::SDebugCell*)((TUint8*)aCell-RHeap::EDebugHdrSize);
+ RHybridHeap::SDebugCell* DbgCell = (RHybridHeap::SDebugCell*)((TUint8*)aCell-RHybridHeap::EDebugHdrSize);
DbgCell->nestingLevel = 0;
}
}
@@ -1105,7 +1105,7 @@ void RHybridHeap::DoCheckSlab(slab* aSlab, TAllocatorType aSlabType, TAny* aBfr)
unsigned used = SlabHeaderUsedm4(h)+4;
unsigned size = SlabHeaderSize(h);
__HEAP_CORRUPTED_TEST( (used < SLABSIZE),ETHeapBadCellAddress, aBfr, aSlab);
- __HEAP_CORRUPTED_TEST( ((size > 3 ) && (size < MAXSLABSIZE)), ETHeapBadCellAddress,aBfr,aSlab);
+ __HEAP_CORRUPTED_TEST( ((size > 3 ) && (size <= MAXSLABSIZE)), ETHeapBadCellAddress,aBfr,aSlab);
unsigned count = 0;
switch ( aSlabType )
diff --git a/src/corelib/arch/symbian/heap_hybrid_p.h b/src/corelib/arch/symbian/heap_hybrid_p.h
index 736af72..95fb3d4 100644
--- a/src/corelib/arch/symbian/heap_hybrid_p.h
+++ b/src/corelib/arch/symbian/heap_hybrid_p.h
@@ -103,11 +103,15 @@ public:
EGetSize=48, EGetMaxLength, EGetBase, EAlignInteger, EAlignAddr
};
enum TDebugOp { EWalk = 128, EHybridHeap };
- enum TAllocFail
+ enum THybridAllocFail
{
ERandom, ETrueRandom, EDeterministic, EHybridNone, EFailNext, EReset, EBurstRandom,
EBurstTrueRandom, EBurstDeterministic, EBurstFailNext, ECheckFailure,
};
+ enum { EDebugHdrSize = sizeof(SDebugCell) };
+#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
+ struct SRAllocatorBurstFail {TInt iBurst; TInt iRate; TInt iUnused[2];};
+#endif
struct HeapInfo
{
diff --git a/src/corelib/arch/symbian/qt_hybridheap_symbian_p.h b/src/corelib/arch/symbian/qt_hybridheap_symbian_p.h
index 5827aca..36c7b6d 100644
--- a/src/corelib/arch/symbian/qt_hybridheap_symbian_p.h
+++ b/src/corelib/arch/symbian/qt_hybridheap_symbian_p.h
@@ -90,7 +90,7 @@
// disabling code ported from Symbian^4 that we don't want/can't have in earlier platforms
#define QT_SYMBIAN4_ALLOCATOR_UNWANTED_CODE
-#if defined(SYMBIAN_VERSION_9_2) || defined(SYMBIAN_VERSION_9_1)
+#if defined(SYMBIAN_VERSION_9_1) || defined(SYMBIAN_VERSION_9_2) || defined(SYMBIAN_VERSION_9_3) || defined(SYMBIAN_VERSION_9_4) || defined(SYMBIAN_VERSION_SYMBIAN2)
#define NO_NAMED_LOCAL_CHUNKS
#endif
@@ -100,6 +100,9 @@ inline int noBTrace() {return 0;}
#define BTraceContext12(a,b,c,d,e) noBTrace()
#endif
+// declare ETHeapBadDebugFailParameter, where missing
+#define ETHeapBadDebugFailParameter ((TCdtPanic)213)
+
#ifndef QT_SYMBIAN_HAVE_U32STD_H
struct SThreadCreateInfo
{
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index a81ed8e..a98d7cc 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -646,7 +646,7 @@ struct QGL2PEVectorPathCache
GLuint ibo;
#else
float *vertices;
- quint32 *indices;
+ void *indices;
#endif
int vertexCount;
int indexCount;
@@ -696,14 +696,6 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());
- // ### Remove before release...
-#ifdef Q_OS_SYMBIAN
- // ### There are some unresolved issues in Symbian vector path caching.
- static bool do_vectorpath_cache = false;
-#else
- static bool do_vectorpath_cache = true;
-#endif
-
// Check to see if there's any hints
if (path.shape() == QVectorPath::RectangleHint) {
QGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y());
@@ -774,8 +766,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
} else {
// printf(" - Marking path as cachable...\n");
// Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable
- if (do_vectorpath_cache)
- path.makeCacheable();
+ path.makeCacheable();
vertexCoordinateArray.clear();
vertexCoordinateArray.addPath(path, inverseScale, false);
prepareForDraw(currentBrush.isOpaque());
@@ -828,13 +819,16 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
cache->indexCount = polys.indices.size();
cache->primitiveType = GL_TRIANGLES;
cache->iscale = inverseScale;
-
#ifdef QT_OPENGL_CACHE_AS_VBOS
glGenBuffers(1, &cache->vbo);
glGenBuffers(1, &cache->ibo);
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
+
+ if (glSupportsElementIndexUint)
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
+ else
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint16) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
QVarLengthArray<float> vertices(polys.vertices.size());
for (int i = 0; i < polys.vertices.size(); ++i)
@@ -842,8 +836,13 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
#else
cache->vertices = (float *) qMalloc(sizeof(float) * polys.vertices.size());
- cache->indices = (quint32 *) qMalloc(sizeof(quint32) * polys.indices.size());
- memcpy(cache->indices, polys.indices.data(), sizeof(quint32) * polys.indices.size());
+ if (glSupportsElementIndexUint) {
+ cache->indices = (quint32 *) qMalloc(sizeof(quint32) * polys.indices.size());
+ memcpy(cache->indices, polys.indices.data(), sizeof(quint32) * polys.indices.size());
+ } else {
+ cache->indices = (quint16 *) qMalloc(sizeof(quint16) * polys.indices.size());
+ memcpy(cache->indices, polys.indices.data(), sizeof(quint16) * polys.indices.size());
+ }
for (int i = 0; i < polys.vertices.size(); ++i)
cache->vertices[i] = float(inverseScale * polys.vertices.at(i));
#endif
@@ -854,19 +853,24 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);
- glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0);
+ if (glSupportsElementIndexUint)
+ glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0);
+ else
+ glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
#else
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);
- glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, cache->indices);
+ if (glSupportsElementIndexUint)
+ glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices);
+ else
+ glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices);
#endif
} else {
// printf(" - Marking path as cachable...\n");
// Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable
- if (do_vectorpath_cache)
- path.makeCacheable();
+ path.makeCacheable();
// The path is too complicated & needs the stencil technique
vertexCoordinateArray.clear();
diff --git a/src/opengl/gl2paintengineex/qtriangulator.cpp b/src/opengl/gl2paintengineex/qtriangulator.cpp
index f14b0a4..bf21240 100644
--- a/src/opengl/gl2paintengineex/qtriangulator.cpp
+++ b/src/opengl/gl2paintengineex/qtriangulator.cpp
@@ -57,6 +57,9 @@
#include <math.h>
+#include "qgl_p.h"
+#include "qglextensions_p.h"
+
QT_BEGIN_NAMESPACE
//#define Q_TRIANGULATOR_DEBUG
@@ -185,6 +188,18 @@ sort_loop_end:
sort(array + low + 1, count - low - 1);
}
+template<typename T>
+struct QVertexSet
+{
+ inline QVertexSet() { }
+ inline QVertexSet(const QVertexSet<T> &other) : vertices(other.vertices), indices(other.indices) { }
+ QVertexSet<T> &operator = (const QVertexSet<T> &other) {vertices = other.vertices; indices = other.indices; return *this;}
+
+ // The vertices of a triangle are given by: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
+ QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
+ QVector<T> indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
+};
+
//============================================================================//
// QFraction //
//============================================================================//
@@ -1295,7 +1310,7 @@ inline void QRingBuffer<T>::enqueue(const T &x)
//============================================================================//
// QTriangulator //
//============================================================================//
-
+template<typename T>
class QTriangulator
{
public:
@@ -1308,7 +1323,7 @@ public:
class ComplexToSimple
{
public:
- inline ComplexToSimple(QTriangulator *parent) : m_parent(parent),
+ inline ComplexToSimple(QTriangulator<T> *parent) : m_parent(parent),
m_edges(0), m_events(0), m_splits(0) { }
void decompose();
private:
@@ -1422,7 +1437,7 @@ public:
class SimpleToMonotone
{
public:
- inline SimpleToMonotone(QTriangulator *parent) : m_parent(parent), m_edges(0), m_upperVertex(0) { }
+ inline SimpleToMonotone(QTriangulator<T> *parent) : m_parent(parent), m_edges(0), m_upperVertex(0) { }
void decompose();
private:
enum VertexType {MergeVertex, EndVertex, RegularVertex, StartVertex, SplitVertex};
@@ -1431,7 +1446,7 @@ public:
{
QRBTree<int>::Node *node;
int helper, twin, next, previous;
- quint32 from, to;
+ T from, to;
VertexType type;
bool pointingUp;
int upper() const {return (pointingUp ? to : from);}
@@ -1478,20 +1493,20 @@ public:
class MonotoneToTriangles
{
public:
- inline MonotoneToTriangles(QTriangulator *parent) : m_parent(parent) { }
+ inline MonotoneToTriangles(QTriangulator<T> *parent) : m_parent(parent) { }
void decompose();
private:
- inline quint32 indices(int index) const {return m_parent->m_indices.at(index + m_first);}
+ inline T indices(int index) const {return m_parent->m_indices.at(index + m_first);}
inline int next(int index) const {return (index + 1) % m_length;}
inline int previous(int index) const {return (index + m_length - 1) % m_length;}
- inline bool less(int i, int j) const {return m_parent->m_vertices.at(indices(i)) < m_parent->m_vertices.at(indices(j));}
+ inline bool less(int i, int j) const {return m_parent->m_vertices.at((qint32)indices(i)) < m_parent->m_vertices.at(indices(j));}
inline bool leftOfEdge(int i, int j, int k) const
{
- return qPointIsLeftOfLine(m_parent->m_vertices.at(indices(i)),
- m_parent->m_vertices.at(indices(j)), m_parent->m_vertices.at(indices(k)));
+ return qPointIsLeftOfLine(m_parent->m_vertices.at((qint32)indices(i)),
+ m_parent->m_vertices.at((qint32)indices(j)), m_parent->m_vertices.at((qint32)indices(k)));
}
- QTriangulator *m_parent;
+ QTriangulator<T> *m_parent;
int m_first;
int m_length;
};
@@ -1505,11 +1520,11 @@ public:
// Call this only once.
void initialize(const QPainterPath &path, const QTransform &matrix, qreal lod);
// Call either triangulate() or polyline() only once.
- QTriangleSet triangulate();
- QPolylineSet polyline();
+ QVertexSet<T> triangulate();
+ QVertexSet<T> polyline();
private:
QDataBuffer<QPodPoint> m_vertices;
- QVector<quint32> m_indices;
+ QVector<T> m_indices;
uint m_hint;
};
@@ -1517,7 +1532,8 @@ private:
// QTriangulator //
//============================================================================//
-QTriangleSet QTriangulator::triangulate()
+template <typename T>
+QVertexSet<T> QTriangulator<T>::triangulate()
{
for (int i = 0; i < m_vertices.size(); ++i) {
Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
@@ -1536,7 +1552,7 @@ QTriangleSet QTriangulator::triangulate()
MonotoneToTriangles m2t(this);
m2t.decompose();
- QTriangleSet result;
+ QVertexSet<T> result;
result.indices = m_indices;
result.vertices.resize(2 * m_vertices.size());
for (int i = 0; i < m_vertices.size(); ++i) {
@@ -1546,9 +1562,10 @@ QTriangleSet QTriangulator::triangulate()
return result;
}
-QPolylineSet QTriangulator::polyline()
+template <typename T>
+QVertexSet<T> QTriangulator<T>::polyline()
{
- QPolylineSet result;
+ QVertexSet<T> result;
result.indices = m_indices;
result.vertices.resize(2 * m_vertices.size());
for (int i = 0; i < m_vertices.size(); ++i) {
@@ -1558,7 +1575,8 @@ QPolylineSet QTriangulator::polyline()
return result;
}
-void QTriangulator::initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix)
+template <typename T>
+void QTriangulator<T>::initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix)
{
m_hint = hint;
m_vertices.resize(count);
@@ -1570,10 +1588,11 @@ void QTriangulator::initialize(const qreal *polygon, int count, uint hint, const
m_vertices.at(i).y = qRound(y * Q_FIXED_POINT_SCALE);
m_indices[i] = i;
}
- m_indices[count] = Q_TRIANGULATE_END_OF_POLYGON;
+ m_indices[count] = T(-1); //Q_TRIANGULATE_END_OF_POLYGON
}
-void QTriangulator::initialize(const QVectorPath &path, const QTransform &matrix, qreal lod)
+template <typename T>
+void QTriangulator<T>::initialize(const QVectorPath &path, const QTransform &matrix, qreal lod)
{
m_hint = path.hints();
// Curved paths will be converted to complex polygons.
@@ -1586,10 +1605,10 @@ void QTriangulator::initialize(const QVectorPath &path, const QTransform &matrix
switch (*e) {
case QPainterPath::MoveToElement:
if (!m_indices.isEmpty())
- m_indices.push_back(Q_TRIANGULATE_END_OF_POLYGON);
+ m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
// Fall through.
case QPainterPath::LineToElement:
- m_indices.push_back(quint32(m_vertices.size()));
+ m_indices.push_back(T(m_vertices.size()));
m_vertices.resize(m_vertices.size() + 1);
qreal x, y;
matrix.map(p[0], p[1], &x, &y);
@@ -1607,7 +1626,7 @@ void QTriangulator::initialize(const QVectorPath &path, const QTransform &matrix
QPolygonF poly = bezier.toPolygon();
// Skip first point, it already exists in 'm_vertices'.
for (int j = 1; j < poly.size(); ++j) {
- m_indices.push_back(quint32(m_vertices.size()));
+ m_indices.push_back(T(m_vertices.size()));
m_vertices.resize(m_vertices.size() + 1);
m_vertices.last().x = qRound(poly.at(j).x() * Q_FIXED_POINT_SCALE / lod);
m_vertices.last().y = qRound(poly.at(j).y() * Q_FIXED_POINT_SCALE / lod);
@@ -1624,7 +1643,7 @@ void QTriangulator::initialize(const QVectorPath &path, const QTransform &matrix
}
} else {
for (int i = 0; i < path.elementCount(); ++i, p += 2) {
- m_indices.push_back(quint32(m_vertices.size()));
+ m_indices.push_back(T(m_vertices.size()));
m_vertices.resize(m_vertices.size() + 1);
qreal x, y;
matrix.map(p[0], p[1], &x, &y);
@@ -1632,10 +1651,11 @@ void QTriangulator::initialize(const QVectorPath &path, const QTransform &matrix
m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
}
}
- m_indices.push_back(Q_TRIANGULATE_END_OF_POLYGON);
+ m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
}
-void QTriangulator::initialize(const QPainterPath &path, const QTransform &matrix, qreal lod)
+template <typename T>
+void QTriangulator<T>::initialize(const QPainterPath &path, const QTransform &matrix, qreal lod)
{
initialize(qtVectorPathForPath(path), matrix, lod);
}
@@ -1643,8 +1663,8 @@ void QTriangulator::initialize(const QPainterPath &path, const QTransform &matri
//============================================================================//
// QTriangulator::ComplexToSimple //
//============================================================================//
-
-void QTriangulator::ComplexToSimple::decompose()
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::decompose()
{
m_initialPointCount = m_parent->m_vertices.size();
initEdges();
@@ -1670,17 +1690,18 @@ void QTriangulator::ComplexToSimple::decompose()
processed.setBit(i);
i = m_edges.at(i).next; // CCW order
} while (i != first);
- m_parent->m_indices.push_back(Q_TRIANGULATE_END_OF_POLYGON);
+ m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
}
}
-void QTriangulator::ComplexToSimple::initEdges()
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::initEdges()
{
// Initialize edge structure.
// 'next' and 'previous' are not being initialized at this point.
int first = 0;
for (int i = 0; i < m_parent->m_indices.size(); ++i) {
- if (m_parent->m_indices.at(i) == Q_TRIANGULATE_END_OF_POLYGON) {
+ if (m_parent->m_indices.at(i) == T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
if (m_edges.size() != first)
m_edges.last().to = m_edges.at(first).from;
first = m_edges.size();
@@ -1700,15 +1721,16 @@ void QTriangulator::ComplexToSimple::initEdges()
}
// Return true if new intersection was found
-bool QTriangulator::ComplexToSimple::calculateIntersection(int left, int right)
+template <typename T>
+bool QTriangulator<T>::ComplexToSimple::calculateIntersection(int left, int right)
{
const Edge &e1 = m_edges.at(left);
const Edge &e2 = m_edges.at(right);
- const QPodPoint &u1 = m_parent->m_vertices.at(e1.from);
- const QPodPoint &u2 = m_parent->m_vertices.at(e1.to);
- const QPodPoint &v1 = m_parent->m_vertices.at(e2.from);
- const QPodPoint &v2 = m_parent->m_vertices.at(e2.to);
+ const QPodPoint &u1 = m_parent->m_vertices.at((qint32)e1.from);
+ const QPodPoint &u2 = m_parent->m_vertices.at((qint32)e1.to);
+ const QPodPoint &v1 = m_parent->m_vertices.at((qint32)e2.from);
+ const QPodPoint &v2 = m_parent->m_vertices.at((qint32)e2.to);
if (qMax(u1.x, u2.x) <= qMin(v1.x, v2.x))
return false;
@@ -1734,7 +1756,8 @@ bool QTriangulator::ComplexToSimple::calculateIntersection(int left, int right)
return true;
}
-bool QTriangulator::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
+template <typename T>
+bool QTriangulator<T>::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
{
const Edge &leftEdge = m_edges.at(leftEdgeIndex);
const Edge &rightEdge = m_edges.at(rightEdgeIndex);
@@ -1752,7 +1775,8 @@ bool QTriangulator::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int rig
return d < 0;
}
-QRBTree<int>::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const
+template <typename T>
+QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const
{
QRBTree<int>::Node *current = m_edgeList.root;
QRBTree<int>::Node *result = 0;
@@ -1767,7 +1791,8 @@ QRBTree<int>::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeInd
return result;
}
-QRBTree<int>::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const
+template <typename T>
+QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const
{
if (!m_edgeList.root)
return after;
@@ -1782,7 +1807,8 @@ QRBTree<int>::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeInd
return result;
}
-QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator::ComplexToSimple::bounds(const QPodPoint &point) const
+template <typename T>
+QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::bounds(const QPodPoint &point) const
{
QRBTree<int>::Node *current = m_edgeList.root;
QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
@@ -1830,7 +1856,8 @@ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator::ComplexToSimple
return result;
}
-QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator::ComplexToSimple::outerBounds(const QPodPoint &point) const
+template <typename T>
+QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::outerBounds(const QPodPoint &point) const
{
QRBTree<int>::Node *current = m_edgeList.root;
QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
@@ -1886,7 +1913,8 @@ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator::ComplexToSimple
return result;
}
-void QTriangulator::ComplexToSimple::splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint)
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint)
{
Q_ASSERT(leftmost && rightmost);
@@ -1904,8 +1932,8 @@ void QTriangulator::ComplexToSimple::splitEdgeListRange(QRBTree<int>::Node *left
}
}
-
-void QTriangulator::ComplexToSimple::reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost)
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost)
{
Q_ASSERT(leftmost && rightmost);
@@ -1932,7 +1960,8 @@ void QTriangulator::ComplexToSimple::reorderEdgeListRange(QRBTree<int>::Node *le
calculateIntersection(storeRightmost->data, rightmost->data);
}
-void QTriangulator::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
{
QIntersectionPoint eventPoint2 = qIntersectionPoint(eventPoint);
while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint < eventPoint2) {
@@ -1949,8 +1978,8 @@ void QTriangulator::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
if (!previous)
break;
const Edge &edge = m_edges.at(previous->data);
- const QPodPoint &u = m_parent->m_vertices.at(edge.from);
- const QPodPoint &v = m_parent->m_vertices.at(edge.to);
+ const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
+ const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
if (!currentIntersectionPoint.isOnLine(u, v)) {
Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
break;
@@ -1963,8 +1992,8 @@ void QTriangulator::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
if (!next)
break;
const Edge &edge = m_edges.at(next->data);
- const QPodPoint &u = m_parent->m_vertices.at(edge.from);
- const QPodPoint &v = m_parent->m_vertices.at(edge.to);
+ const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
+ const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
if (!currentIntersectionPoint.isOnLine(u, v)) {
Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
break;
@@ -1987,7 +2016,8 @@ void QTriangulator::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
}
}
-void QTriangulator::ComplexToSimple::fillPriorityQueue()
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::fillPriorityQueue()
{
m_events.reset();
m_events.reserve(m_edges.size() * 2);
@@ -2010,7 +2040,8 @@ void QTriangulator::ComplexToSimple::fillPriorityQueue()
sort(m_events.data(), m_events.size());
}
-void QTriangulator::ComplexToSimple::calculateIntersections()
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::calculateIntersections()
{
fillPriorityQueue();
@@ -2075,7 +2106,8 @@ void QTriangulator::ComplexToSimple::calculateIntersections()
// The upper piece is pushed to the end of the 'm_edges' vector.
// The lower piece replaces the old edge.
// Return the edge whose 'from' is 'pointIndex'.
-int QTriangulator::ComplexToSimple::splitEdge(int splitIndex)
+template <typename T>
+int QTriangulator<T>::ComplexToSimple::splitEdge(int splitIndex)
{
const Split &split = m_splits.at(splitIndex);
Edge &lowerEdge = m_edges.at(split.edge);
@@ -2105,7 +2137,8 @@ int QTriangulator::ComplexToSimple::splitEdge(int splitIndex)
}
}
-bool QTriangulator::ComplexToSimple::splitEdgesAtIntersections()
+template <typename T>
+bool QTriangulator<T>::ComplexToSimple::splitEdgesAtIntersections()
{
for (int i = 0; i < m_edges.size(); ++i)
m_edges.at(i).mayIntersect = false;
@@ -2122,7 +2155,8 @@ bool QTriangulator::ComplexToSimple::splitEdgesAtIntersections()
return checkForNewIntersections;
}
-void QTriangulator::ComplexToSimple::insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i)
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i)
{
// Edges with zero length should not reach this part.
Q_ASSERT(m_parent->m_vertices.at(m_edges.at(i).from) != m_parent->m_vertices.at(m_edges.at(i).to));
@@ -2152,7 +2186,8 @@ void QTriangulator::ComplexToSimple::insertEdgeIntoVectorIfWanted(ShortArray &or
orderedEdges.append(i);
}
-void QTriangulator::ComplexToSimple::removeUnwantedEdgesAndConnect()
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::removeUnwantedEdgesAndConnect()
{
Q_ASSERT(m_edgeList.root == 0);
// Initialize priority queue.
@@ -2290,7 +2325,8 @@ void QTriangulator::ComplexToSimple::removeUnwantedEdgesAndConnect()
} // end while
}
-void QTriangulator::ComplexToSimple::removeUnusedPoints() {
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::removeUnusedPoints() {
QBitArray used(m_parent->m_vertices.size(), false);
for (int i = 0; i < m_edges.size(); ++i) {
Q_ASSERT((m_edges.at(i).previous == -1) == (m_edges.at(i).next == -1));
@@ -2314,7 +2350,8 @@ void QTriangulator::ComplexToSimple::removeUnusedPoints() {
}
}
-bool QTriangulator::ComplexToSimple::CompareEdges::operator () (int i, int j) const
+template <typename T>
+bool QTriangulator<T>::ComplexToSimple::CompareEdges::operator () (int i, int j) const
{
int cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from),
m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from));
@@ -2325,7 +2362,8 @@ bool QTriangulator::ComplexToSimple::CompareEdges::operator () (int i, int j) co
return cmp > 0;
}
-inline bool QTriangulator::ComplexToSimple::Event::operator < (const Event &other) const
+template <typename T>
+inline bool QTriangulator<T>::ComplexToSimple::Event::operator < (const Event &other) const
{
if (point == other.point)
return type < other.type; // 'Lower' has higher priority than 'Upper'.
@@ -2337,8 +2375,8 @@ inline bool QTriangulator::ComplexToSimple::Event::operator < (const Event &othe
//============================================================================//
#ifdef Q_TRIANGULATOR_DEBUG
-
-QTriangulator::ComplexToSimple::DebugDialog::DebugDialog(ComplexToSimple *parent, int currentVertex)
+template <typename T>
+QTriangulator<T>::ComplexToSimple::DebugDialog::DebugDialog(ComplexToSimple *parent, int currentVertex)
: m_parent(parent), m_vertex(currentVertex)
{
QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
@@ -2360,7 +2398,8 @@ QTriangulator::ComplexToSimple::DebugDialog::DebugDialog(ComplexToSimple *parent
m_window = QRectF(minX - border, minY - border, (maxX - minX + 2 * border), (maxY - minY + 2 * border));
}
-void QTriangulator::ComplexToSimple::DebugDialog::paintEvent(QPaintEvent *)
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::DebugDialog::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing, true);
@@ -2426,7 +2465,8 @@ void QTriangulator::ComplexToSimple::DebugDialog::paintEvent(QPaintEvent *)
}
}
-void QTriangulator::ComplexToSimple::DebugDialog::wheelEvent(QWheelEvent *event)
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::DebugDialog::wheelEvent(QWheelEvent *event)
{
qreal scale = exp(-0.001 * event->delta());
QPointF center = m_window.center();
@@ -2436,7 +2476,8 @@ void QTriangulator::ComplexToSimple::DebugDialog::wheelEvent(QWheelEvent *event)
update();
}
-void QTriangulator::ComplexToSimple::DebugDialog::mouseMoveEvent(QMouseEvent *event)
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::DebugDialog::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
QPointF delta = event->pos() - m_lastMousePos;
@@ -2449,7 +2490,8 @@ void QTriangulator::ComplexToSimple::DebugDialog::mouseMoveEvent(QMouseEvent *ev
}
}
-void QTriangulator::ComplexToSimple::DebugDialog::mousePressEvent(QMouseEvent *event)
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::DebugDialog::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
m_lastMousePos = event->pos();
@@ -2462,8 +2504,8 @@ void QTriangulator::ComplexToSimple::DebugDialog::mousePressEvent(QMouseEvent *e
//============================================================================//
// QTriangulator::SimpleToMonotone //
//============================================================================//
-
-void QTriangulator::SimpleToMonotone::decompose()
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::decompose()
{
setupDataStructures();
removeZeroLengthEdges();
@@ -2482,12 +2524,13 @@ void QTriangulator::SimpleToMonotone::decompose()
processed.setBit(i);
i = m_edges.at(i).next;
} while (i != first);
- if (m_parent->m_indices.size() > 0 && m_parent->m_indices.back() != Q_TRIANGULATE_END_OF_POLYGON)
- m_parent->m_indices.push_back(Q_TRIANGULATE_END_OF_POLYGON);
+ if (m_parent->m_indices.size() > 0 && m_parent->m_indices.back() != T(-1)) // Q_TRIANGULATE_END_OF_POLYGON
+ m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
}
}
-void QTriangulator::SimpleToMonotone::setupDataStructures()
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::setupDataStructures()
{
int i = 0;
Edge e;
@@ -2505,7 +2548,7 @@ void QTriangulator::SimpleToMonotone::setupDataStructures()
m_edges.add(e);
++i;
Q_ASSERT(i < m_parent->m_indices.size());
- } while (m_parent->m_indices.at(i) != Q_TRIANGULATE_END_OF_POLYGON);
+ } while (m_parent->m_indices.at(i) != T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
m_edges.last().next = start;
m_edges.at(start).previous = m_edges.size() - 1;
@@ -2519,7 +2562,8 @@ void QTriangulator::SimpleToMonotone::setupDataStructures()
}
}
-void QTriangulator::SimpleToMonotone::removeZeroLengthEdges()
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::removeZeroLengthEdges()
{
for (int i = 0; i < m_edges.size(); ++i) {
if (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(i).to)) {
@@ -2547,7 +2591,8 @@ void QTriangulator::SimpleToMonotone::removeZeroLengthEdges()
}
}
-void QTriangulator::SimpleToMonotone::fillPriorityQueue()
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::fillPriorityQueue()
{
m_upperVertex.reset();
m_upperVertex.reserve(m_edges.size());
@@ -2561,7 +2606,8 @@ void QTriangulator::SimpleToMonotone::fillPriorityQueue()
//}
}
-bool QTriangulator::SimpleToMonotone::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
+template <typename T>
+bool QTriangulator<T>::SimpleToMonotone::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
{
const Edge &leftEdge = m_edges.at(leftEdgeIndex);
const Edge &rightEdge = m_edges.at(rightEdgeIndex);
@@ -2575,7 +2621,8 @@ bool QTriangulator::SimpleToMonotone::edgeIsLeftOfEdge(int leftEdgeIndex, int ri
}
// Returns the rightmost edge not to the right of the given edge.
-QRBTree<int>::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfEdge(int edgeIndex) const
+template <typename T>
+QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfEdge(int edgeIndex) const
{
QRBTree<int>::Node *current = m_edgeList.root;
QRBTree<int>::Node *result = 0;
@@ -2591,7 +2638,8 @@ QRBTree<int>::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfEdge(int ed
}
// Returns the rightmost edge left of the given point.
-QRBTree<int>::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfPoint(int pointIndex) const
+template <typename T>
+QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfPoint(int pointIndex) const
{
QRBTree<int>::Node *current = m_edgeList.root;
QRBTree<int>::Node *result = 0;
@@ -2609,7 +2657,8 @@ QRBTree<int>::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfPoint(int p
return result;
}
-void QTriangulator::SimpleToMonotone::classifyVertex(int i)
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::classifyVertex(int i)
{
Edge &e2 = m_edges.at(i);
const Edge &e1 = m_edges.at(e2.previous);
@@ -2638,13 +2687,15 @@ void QTriangulator::SimpleToMonotone::classifyVertex(int i)
}
}
-void QTriangulator::SimpleToMonotone::classifyVertices()
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::classifyVertices()
{
for (int i = 0; i < m_edges.size(); ++i)
classifyVertex(i);
}
-bool QTriangulator::SimpleToMonotone::pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3)
+template <typename T>
+bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3)
{
bool leftOfPreviousEdge = !qPointIsLeftOfLine(p, v2, v1);
bool leftOfNextEdge = !qPointIsLeftOfLine(p, v3, v2);
@@ -2655,7 +2706,8 @@ bool QTriangulator::SimpleToMonotone::pointIsInSector(const QPodPoint &p, const
return leftOfPreviousEdge || leftOfNextEdge;
}
-bool QTriangulator::SimpleToMonotone::pointIsInSector(int vertex, int sector)
+template <typename T>
+bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(int vertex, int sector)
{
const QPodPoint &center = m_parent->m_vertices.at(m_edges.at(sector).from);
// Handle degenerate edges.
@@ -2677,7 +2729,8 @@ bool QTriangulator::SimpleToMonotone::pointIsInSector(int vertex, int sector)
return pointIsInSector(p, v1, center, v3);
}
-int QTriangulator::SimpleToMonotone::findSector(int edge, int vertex)
+template <typename T>
+int QTriangulator<T>::SimpleToMonotone::findSector(int edge, int vertex)
{
while (!pointIsInSector(vertex, edge)) {
edge = m_edges.at(m_edges.at(edge).previous).twin;
@@ -2686,7 +2739,8 @@ int QTriangulator::SimpleToMonotone::findSector(int edge, int vertex)
return edge;
}
-void QTriangulator::SimpleToMonotone::createDiagonal(int lower, int upper)
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::createDiagonal(int lower, int upper)
{
lower = findSector(lower, upper);
upper = findSector(upper, lower);
@@ -2713,7 +2767,8 @@ void QTriangulator::SimpleToMonotone::createDiagonal(int lower, int upper)
m_edges.add(e);
}
-void QTriangulator::SimpleToMonotone::monotoneDecomposition()
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::monotoneDecomposition()
{
if (m_edges.isEmpty())
return;
@@ -2729,8 +2784,8 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition()
Q_ASSERT(i < m_edges.size());
int j = m_edges.at(i).previous;
Q_ASSERT(j < m_edges.size());
- m_clockwiseOrder = qPointIsLeftOfLine(m_parent->m_vertices.at(m_edges.at(i).from),
- m_parent->m_vertices.at(m_edges.at(j).from), m_parent->m_vertices.at(m_edges.at(i).to));
+ m_clockwiseOrder = qPointIsLeftOfLine(m_parent->m_vertices.at((quint32)m_edges.at(i).from),
+ m_parent->m_vertices.at((quint32)m_edges.at(j).from), m_parent->m_vertices.at((quint32)m_edges.at(i).to));
classifyVertices();
fillPriorityQueue();
@@ -2848,7 +2903,8 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition()
createDiagonal(diagonals.at(i).first, diagonals.at(i).second);
}
-bool QTriangulator::SimpleToMonotone::CompareVertices::operator () (int i, int j) const
+template <typename T>
+bool QTriangulator<T>::SimpleToMonotone::CompareVertices::operator () (int i, int j) const
{
if (m_parent->m_edges.at(i).from == m_parent->m_edges.at(j).from)
return m_parent->m_edges.at(i).type > m_parent->m_edges.at(j).type;
@@ -2859,16 +2915,16 @@ bool QTriangulator::SimpleToMonotone::CompareVertices::operator () (int i, int j
//============================================================================//
// QTriangulator::MonotoneToTriangles //
//============================================================================//
-
-void QTriangulator::MonotoneToTriangles::decompose()
+template <typename T>
+void QTriangulator<T>::MonotoneToTriangles::decompose()
{
- QVector<quint32> result;
+ QVector<T> result;
QDataBuffer<int> stack(m_parent->m_indices.size());
m_first = 0;
// Require at least three more indices.
while (m_first + 3 <= m_parent->m_indices.size()) {
m_length = 0;
- while (m_parent->m_indices.at(m_first + m_length) != Q_TRIANGULATE_END_OF_POLYGON) {
+ while (m_parent->m_indices.at(m_first + m_length) != T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
++m_length;
Q_ASSERT(m_first + m_length < m_parent->m_indices.size());
}
@@ -2955,39 +3011,115 @@ void QTriangulator::MonotoneToTriangles::decompose()
// qTriangulate //
//============================================================================//
-QTriangleSet qTriangulate(const qreal *polygon, int count, uint hint, const QTransform &matrix)
+QTriangleSet qTriangulate(const qreal *polygon,
+ int count, uint hint, const QTransform &matrix)
{
- QTriangulator triangulator;
- triangulator.initialize(polygon, count, hint, matrix);
- return triangulator.triangulate();
+ QGLContext *ctx = 0; // Not really used but needs to be introduced for glSupportsElementIndexUint
+
+ QTriangleSet triangleSet;
+ if (glSupportsElementIndexUint) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(polygon, count, hint, matrix);
+ QVertexSet<quint32> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUint(vertexSet.indices);
+
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(polygon, count, hint, matrix);
+ QVertexSet<quint16> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return triangleSet;
}
-QTriangleSet qTriangulate(const QVectorPath &path, const QTransform &matrix, qreal lod)
+QTriangleSet qTriangulate(const QVectorPath &path,
+ const QTransform &matrix, qreal lod)
{
- QTriangulator triangulator;
- triangulator.initialize(path, matrix, lod);
- return triangulator.triangulate();
+ QGLContext *ctx = 0; // Not really used but needs to be introduced for glSupportsElementIndexUint
+
+ QTriangleSet triangleSet;
+ if (glSupportsElementIndexUint) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint32> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUint(vertexSet.indices);
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint16> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return triangleSet;
}
-QTriangleSet qTriangulate(const QPainterPath &path, const QTransform &matrix, qreal lod)
+QTriangleSet qTriangulate(const QPainterPath &path,
+ const QTransform &matrix, qreal lod)
{
- QTriangulator triangulator;
- triangulator.initialize(path, matrix, lod);
- return triangulator.triangulate();
+ QGLContext *ctx = 0; // Not really used but needs to be introduced for glSupportsElementIndexUint
+
+ QTriangleSet triangleSet;
+ if (glSupportsElementIndexUint) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint32> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUint(vertexSet.indices);
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint16> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return triangleSet;
}
-QPolylineSet qPolyline(const QVectorPath &path, const QTransform &matrix, qreal lod)
+QPolylineSet qPolyline(const QVectorPath &path,
+ const QTransform &matrix, qreal lod)
{
- QTriangulator triangulator;
- triangulator.initialize(path, matrix, lod);
- return triangulator.polyline();
+ QGLContext *ctx = 0; // Not really used but needs to be introduced for glSupportsElementIndexUint
+
+ QPolylineSet polyLineSet;
+ if (glSupportsElementIndexUint) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint32> vertexSet = triangulator.polyline();
+ polyLineSet.vertices = vertexSet.vertices;
+ polyLineSet.indices.setDataUint(vertexSet.indices);
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint16> vertexSet = triangulator.triangulate();
+ polyLineSet.vertices = vertexSet.vertices;
+ polyLineSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return polyLineSet;
}
-QPolylineSet qPolyline(const QPainterPath &path, const QTransform &matrix, qreal lod)
+QPolylineSet qPolyline(const QPainterPath &path,
+ const QTransform &matrix, qreal lod)
{
- QTriangulator triangulator;
- triangulator.initialize(path, matrix, lod);
- return triangulator.polyline();
+ QGLContext *ctx = 0; // Not really used but needs to be introduced for glSupportsElementIndexUint
+
+ QPolylineSet polyLineSet;
+ if (glSupportsElementIndexUint) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint32> vertexSet = triangulator.polyline();
+ polyLineSet.vertices = vertexSet.vertices;
+ polyLineSet.indices.setDataUint(vertexSet.indices);
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint16> vertexSet = triangulator.triangulate();
+ polyLineSet.vertices = vertexSet.vertices;
+ polyLineSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return polyLineSet;
}
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qtriangulator_p.h b/src/opengl/gl2paintengineex/qtriangulator_p.h
index e5eec39..8f96e9f 100644
--- a/src/opengl/gl2paintengineex/qtriangulator_p.h
+++ b/src/opengl/gl2paintengineex/qtriangulator_p.h
@@ -58,7 +58,58 @@
QT_BEGIN_NAMESPACE
-#define Q_TRIANGULATE_END_OF_POLYGON quint32(-1)
+class QVertexIndexVector
+{
+public:
+ enum Type {
+ UnsignedInt,
+ UnsignedShort
+ };
+
+ inline Type type() const { return t; }
+
+ inline void setDataUint(const QVector<quint32> &data)
+ {
+ t = UnsignedInt;
+ indices32 = data;
+ }
+
+ inline void setDataUshort(const QVector<quint16> &data)
+ {
+ t = UnsignedShort;
+ indices16 = data;
+ }
+
+ inline const void* data() const
+ {
+ if (t == UnsignedInt)
+ return indices32.data();
+ return indices16.data();
+ }
+
+ inline int size() const
+ {
+ if (t == UnsignedInt)
+ return indices32.size();
+ return indices16.size();
+ }
+
+ inline QVertexIndexVector &operator = (const QVertexIndexVector &other)
+ {
+ if (t == UnsignedInt)
+ indices32 = other.indices32;
+ else
+ indices16 = other.indices16;
+
+ return *this;
+ }
+
+private:
+
+ Type t;
+ QVector<quint32> indices32;
+ QVector<quint16> indices16;
+};
struct QTriangleSet
{
@@ -68,7 +119,7 @@ struct QTriangleSet
// The vertices of a triangle are given by: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
- QVector<quint32> indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
+ QVertexIndexVector indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
};
struct QPolylineSet
@@ -78,8 +129,7 @@ struct QPolylineSet
QPolylineSet &operator = (const QPolylineSet &other) {vertices = other.vertices; indices = other.indices; return *this;}
QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
- QVector<quint32> indices;
-
+ QVertexIndexVector indices;
};
// The vertex coordinates of the returned triangle set will be rounded to a grid with a mesh size
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index 6259cca..e81e849 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -346,6 +346,17 @@ struct QGLExtensionFuncs
qt_glEGLImageTargetTexture2DOES = 0;
qt_glEGLImageTargetRenderbufferStorageOES = 0;
#endif
+
+ // OES_element_index_uint
+#if !defined(QT_OPENGL_ES)
+ qt_glSupportsElementIndexUint = true;
+#else
+ QString extensions = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
+ if (extensions.contains("GL_OES_element_index_uint"))
+ qt_glSupportsElementIndexUint = true;
+ else
+ qt_glSupportsElementIndexUint = false;
+#endif
}
@@ -473,6 +484,7 @@ struct QGLExtensionFuncs
_glEGLImageTargetRenderbufferStorageOES qt_glEGLImageTargetRenderbufferStorageOES;
#endif
+ bool qt_glSupportsElementIndexUint;
};
@@ -871,6 +883,8 @@ struct QGLExtensionFuncs
#define glEGLImageTargetRenderbufferStorageOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetRenderbufferStorageOES
#endif
+#define glSupportsElementIndexUint QGLContextPrivate::extensionFuncs(ctx).qt_glSupportsElementIndexUint
+
extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx);
bool qt_resolve_buffer_extensions(QGLContext *ctx);
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index 74395a2..f6d2435 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -196,9 +196,7 @@ public:
#endif
QTransform transform; // Currently active transform.
- bool affineTransform; // True if the transform is non-projective.
- bool simpleTransform; // True if the transform is simple translate
- // or 0, 90, 180, and 270 degree rotation
+ bool simpleTransform; // True if the transform is simple (non-projective).
qreal penScale; // Pen scaling factor from "transform".
QTransform pathTransform; // Calculated VG path transformation.
@@ -379,7 +377,6 @@ void QVGPaintEnginePrivate::init()
roundRectPath = 0;
#endif
- affineTransform = true;
simpleTransform = true;
pathTransformSet = false;
penScale = 1.0;
@@ -532,59 +529,12 @@ void QVGPaintEnginePrivate::setTransform
vgLoadMatrix(mat);
}
-// Determine if a co-ordinate transform is simple enough to allow
-// rectangle-based clipping with vgMask() and rounding translation
-// to integers. Simple transforms most often result from origin translations.
-static inline bool transformIsSimple(const QTransform& transform)
-{
- QTransform::TransformationType type = transform.type();
- if (type == QTransform::TxNone || type == QTransform::TxTranslate) {
- return true;
- } else if (type == QTransform::TxScale) {
- // Check for 0 and 180 degree rotations.
- // (0 might happen after 4 rotations of 90 degrees).
- qreal m11 = transform.m11();
- qreal m12 = transform.m12();
- qreal m21 = transform.m21();
- qreal m22 = transform.m22();
- if (m12 == 0.0f && m21 == 0.0f) {
- if (m11 == 1.0f && m22 == 1.0f)
- return true; // 0 degrees
- else if (m11 == -1.0f && m22 == -1.0f)
- return true; // 180 degrees.
- if(m11 == 1.0f && m22 == -1.0f)
- return true; // 0 degrees inverted y.
- else if(m11 == -1.0f && m22 == 1.0f)
- return true; // 180 degrees inverted y.
- }
- } else if (type == QTransform::TxRotate) {
- // Check for 90, and 270 degree rotations.
- qreal m11 = transform.m11();
- qreal m12 = transform.m12();
- qreal m21 = transform.m21();
- qreal m22 = transform.m22();
- if (m11 == 0.0f && m22 == 0.0f) {
- if (m12 == 1.0f && m21 == -1.0f)
- return true; // 90 degrees.
- else if (m12 == -1.0f && m21 == 1.0f)
- return true; // 270 degrees.
- else if (m12 == -1.0f && m21 == -1.0f)
- return true; // 90 degrees inverted y.
- else if (m12 == 1.0f && m21 == 1.0f)
- return true; // 270 degrees inverted y.
- }
- }
- return false;
-}
-
Q_DECL_IMPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev)
{
VGfloat devh = pdev->height();
- simpleTransform = transformIsSimple(transform);
-
// Construct the VG transform by combining the Qt transform with
// the following viewport transformation:
// | 1 0 0 |
@@ -607,9 +557,9 @@ void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev)
// so we will have to convert the co-ordinates ourselves.
// Change the matrix to just the viewport transformation.
pathTransform = viewport;
- affineTransform = false;
+ simpleTransform = false;
} else {
- affineTransform = true;
+ simpleTransform = true;
}
pathTransformSet = false;
@@ -638,7 +588,7 @@ VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path)
// Size is sufficient segments for drawRoundedRect() paths.
QVarLengthArray<VGubyte, 20> segments;
- if (sizeof(qreal) == sizeof(VGfloat) && elements && affineTransform) {
+ if (sizeof(qreal) == sizeof(VGfloat) && elements && simpleTransform) {
// If Qt was compiled with qreal the same size as VGfloat,
// then convert the segment types and use the incoming
// points array directly.
@@ -673,7 +623,7 @@ VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path)
int curvePos = 0;
QPointF temp;
- if (elements && affineTransform) {
+ if (elements && simpleTransform) {
// Convert the members of the element array.
for (int i = 0; i < count; ++i) {
switch (elements[i]) {
@@ -717,7 +667,7 @@ VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path)
}
points += 2;
}
- } else if (elements && !affineTransform) {
+ } else if (elements && !simpleTransform) {
// Convert the members of the element array after applying the
// current transform to the path locally.
for (int i = 0; i < count; ++i) {
@@ -766,7 +716,7 @@ VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path)
}
points += 2;
}
- } else if (count > 0 && affineTransform) {
+ } else if (count > 0 && simpleTransform) {
// If there is no element array, then the path is assumed
// to be a MoveTo followed by several LineTo's.
coords.append(points[0]);
@@ -779,7 +729,7 @@ VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path)
segments.append(VG_LINE_TO_ABS);
--count;
}
- } else if (count > 0 && !affineTransform) {
+ } else if (count > 0 && !simpleTransform) {
// Convert a simple path, and apply the transform locally.
temp = transform.map(QPointF(points[0], points[1]));
coords.append(temp.x());
@@ -840,7 +790,7 @@ VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path)
bool haveStart = false;
bool haveEnd = false;
- if (affineTransform) {
+ if (simpleTransform) {
// Convert the members of the element array.
for (int i = 0; i < count; ++i) {
switch (elements[i].type) {
@@ -1615,6 +1565,36 @@ void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
vgDestroyPath(vgpath);
}
+// Determine if a co-ordinate transform is simple enough to allow
+// rectangle-based clipping with vgMask(). Simple transforms most
+// often result from origin translations.
+static inline bool clipTransformIsSimple(const QTransform& transform)
+{
+ QTransform::TransformationType type = transform.type();
+ if (type == QTransform::TxNone || type == QTransform::TxTranslate)
+ return true;
+ if (type == QTransform::TxRotate) {
+ // Check for 0, 90, 180, and 270 degree rotations.
+ // (0 might happen after 4 rotations of 90 degrees).
+ qreal m11 = transform.m11();
+ qreal m12 = transform.m12();
+ qreal m21 = transform.m21();
+ qreal m22 = transform.m22();
+ if (m11 == 0.0f && m22 == 0.0f) {
+ if (m12 == 1.0f && m21 == -1.0f)
+ return true; // 90 degrees.
+ else if (m12 == -1.0f && m21 == 1.0f)
+ return true; // 270 degrees.
+ } else if (m12 == 0.0f && m21 == 0.0f) {
+ if (m11 == -1.0f && m22 == -1.0f)
+ return true; // 180 degrees.
+ else if (m11 == 1.0f && m22 == 1.0f)
+ return true; // 0 degrees.
+ }
+ }
+ return false;
+}
+
#if defined(QVG_SCISSOR_CLIP)
void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
@@ -1632,7 +1612,7 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
// We aren't using masking, so handle simple QRectF's only.
if (path.shape() == QVectorPath::RectangleHint &&
- path.elementCount() == 4 && d->simpleTransform) {
+ path.elementCount() == 4 && clipTransformIsSimple(d->transform)) {
// Clipping region that resulted from QPainter::setClipRect(QRectF).
// Convert it into a QRect and apply.
const qreal *points = path.points();
@@ -1782,7 +1762,7 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
// We don't have vgRenderToMask(), so handle simple QRectF's only.
if (path.shape() == QVectorPath::RectangleHint &&
- path.elementCount() == 4 && d->simpleTransform) {
+ path.elementCount() == 4 && clipTransformIsSimple(d->transform)) {
// Clipping region that resulted from QPainter::setClipRect(QRectF).
// Convert it into a QRect and apply.
const qreal *points = path.points();
@@ -1834,7 +1814,7 @@ void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
d->dirty |= QPaintEngine::DirtyClipRegion;
// If we have a non-simple transform, then use path-based clipping.
- if (op != Qt::NoClip && !d->simpleTransform) {
+ if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) {
QPaintEngineEx::clip(rect, op);
return;
}
@@ -1953,7 +1933,7 @@ void QVGPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
d->dirty |= QPaintEngine::DirtyClipRegion;
// If we have a non-simple transform, then use path-based clipping.
- if (op != Qt::NoClip && !d->simpleTransform) {
+ if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) {
QPaintEngineEx::clip(region, op);
return;
}
@@ -2530,14 +2510,14 @@ void QVGPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
// Check to see if we can use vgClear() for faster filling.
if (brush.style() == Qt::SolidPattern && brush.isOpaque() &&
- d->simpleTransform && d->opacity == 1.0f &&
+ clipTransformIsSimple(d->transform) && d->opacity == 1.0f &&
clearRect(rect, brush.color())) {
return;
}
#if !defined(QVG_NO_MODIFY_PATH)
VGfloat coords[8];
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords[0] = rect.x();
coords[1] = rect.y();
coords[2] = rect.x() + rect.width();
@@ -2572,14 +2552,14 @@ void QVGPaintEngine::fillRect(const QRectF &rect, const QColor &color)
Q_D(QVGPaintEngine);
// Check to see if we can use vgClear() for faster filling.
- if (d->simpleTransform && d->opacity == 1.0f && color.alpha() == 255 &&
+ if (clipTransformIsSimple(d->transform) && d->opacity == 1.0f && color.alpha() == 255 &&
clearRect(rect, color)) {
return;
}
#if !defined(QVG_NO_MODIFY_PATH)
VGfloat coords[8];
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords[0] = rect.x();
coords[1] = rect.y();
coords[2] = rect.x() + rect.width();
@@ -2612,7 +2592,7 @@ void QVGPaintEngine::fillRect(const QRectF &rect, const QColor &color)
void QVGPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode)
{
Q_D(QVGPaintEngine);
- if (d->affineTransform) {
+ if (d->simpleTransform) {
QVGPainterState *s = state();
VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode);
d->draw(vgpath, s->pen, s->brush);
@@ -2631,7 +2611,7 @@ void QVGPaintEngine::drawRects(const QRect *rects, int rectCount)
QVGPainterState *s = state();
for (int i = 0; i < rectCount; ++i, ++rects) {
VGfloat coords[8];
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords[0] = rects->x();
coords[1] = rects->y();
coords[2] = rects->x() + rects->width();
@@ -2672,7 +2652,7 @@ void QVGPaintEngine::drawRects(const QRectF *rects, int rectCount)
QVGPainterState *s = state();
for (int i = 0; i < rectCount; ++i, ++rects) {
VGfloat coords[8];
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords[0] = rects->x();
coords[1] = rects->y();
coords[2] = rects->x() + rects->width();
@@ -2710,7 +2690,7 @@ void QVGPaintEngine::drawLines(const QLine *lines, int lineCount)
QVGPainterState *s = state();
for (int i = 0; i < lineCount; ++i, ++lines) {
VGfloat coords[4];
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords[0] = lines->x1();
coords[1] = lines->y1();
coords[2] = lines->x2();
@@ -2738,7 +2718,7 @@ void QVGPaintEngine::drawLines(const QLineF *lines, int lineCount)
QVGPainterState *s = state();
for (int i = 0; i < lineCount; ++i, ++lines) {
VGfloat coords[4];
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords[0] = lines->x1();
coords[1] = lines->y1();
coords[2] = lines->x2();
@@ -2764,7 +2744,7 @@ void QVGPaintEngine::drawEllipse(const QRectF &r)
// Based on the description of vguEllipse() in the OpenVG specification.
// We don't use vguEllipse(), to avoid unnecessary library dependencies.
Q_D(QVGPaintEngine);
- if (d->affineTransform) {
+ if (d->simpleTransform) {
QVGPainterState *s = state();
VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD,
VG_PATH_DATATYPE_F,
@@ -2837,7 +2817,7 @@ void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount)
for (int i = 0; i < pointCount; ++i, ++points) {
VGfloat coords[4];
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords[0] = points->x();
coords[1] = points->y();
coords[2] = coords[0];
@@ -2871,7 +2851,7 @@ void QVGPaintEngine::drawPoints(const QPoint *points, int pointCount)
for (int i = 0; i < pointCount; ++i, ++points) {
VGfloat coords[4];
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords[0] = points->x();
coords[1] = points->y();
coords[2] = coords[0];
@@ -2905,7 +2885,7 @@ void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonD
QVarLengthArray<VGfloat, 16> coords;
QVarLengthArray<VGubyte, 10> segments;
for (int i = 0; i < pointCount; ++i, ++points) {
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords.append(points->x());
coords.append(points->y());
} else {
@@ -2952,7 +2932,7 @@ void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDr
QVarLengthArray<VGfloat, 16> coords;
QVarLengthArray<VGubyte, 10> segments;
for (int i = 0; i < pointCount; ++i, ++points) {
- if (d->affineTransform) {
+ if (d->simpleTransform) {
coords.append(points->x());
coords.append(points->y());
} else {
@@ -2987,7 +2967,7 @@ void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDr
void QVGPaintEnginePrivate::setImageOptions()
{
- if (opacity != 1.0f && affineTransform) {
+ if (opacity != 1.0f && simpleTransform) {
if (opacity != paintOpacity) {
VGfloat values[4];
values[0] = 1.0f;
@@ -3034,10 +3014,7 @@ static void drawVGImage(QVGPaintEnginePrivate *d,
QTransform transform(d->imageTransform);
VGfloat scaleX = sr.width() == 0.0f ? 0.0f : r.width() / sr.width();
VGfloat scaleY = sr.height() == 0.0f ? 0.0f : r.height() / sr.height();
- if (d->simpleTransform)
- transform.translate(qRound(r.x()), qRound(r.y()));
- else
- transform.translate(r.x(), r.y());
+ transform.translate(r.x(), r.y());
transform.scale(scaleX, scaleY);
d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
@@ -3055,10 +3032,7 @@ static void drawVGImage(QVGPaintEnginePrivate *d,
return;
QTransform transform(d->imageTransform);
- if(d->simpleTransform)
- transform.translate(qRound(pos.x()), qRound(pos.y()));
- else
- transform.translate(pos.x(), pos.y());
+ transform.translate(pos.x(), pos.y());
d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
d->setImageOptions();
@@ -3101,7 +3075,7 @@ void QVGPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF
QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
if (!vgpd->isValid())
return;
- if (d->affineTransform)
+ if (d->simpleTransform)
drawVGImage(d, r, vgpd->toVGImage(), vgpd->size(), sr);
else
drawVGImage(d, r, vgpd->toVGImage(d->opacity), vgpd->size(), sr);
@@ -3120,7 +3094,7 @@ void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
if (!vgpd->isValid())
return;
- if (d->affineTransform)
+ if (d->simpleTransform)
drawVGImage(d, pos, vgpd->toVGImage());
else
drawVGImage(d, pos, vgpd->toVGImage(d->opacity));
@@ -3135,7 +3109,7 @@ void QVGPaintEngine::drawImage
{
Q_D(QVGPaintEngine);
VGImage vgImg;
- if (d->affineTransform || d->opacity == 1.0f)
+ if (d->simpleTransform || d->opacity == 1.0f)
vgImg = toVGImageSubRect(image, sr.toRect(), flags);
else
vgImg = toVGImageWithOpacitySubRect(image, d->opacity, sr.toRect());
@@ -3158,7 +3132,7 @@ void QVGPaintEngine::drawImage(const QPointF &pos, const QImage &image)
{
Q_D(QVGPaintEngine);
VGImage vgImg;
- if (d->affineTransform || d->opacity == 1.0f)
+ if (d->simpleTransform || d->opacity == 1.0f)
vgImg = toVGImage(image);
else
vgImg = toVGImageWithOpacity(image, d->opacity);
@@ -3191,7 +3165,7 @@ void QVGPaintEngine::drawPixmapFragments(const QPainter::PixmapFragment *drawing
QPixmapData *pd = pixmap.pixmapData();
if (!pd)
return; // null QPixmap
- if (pd->classId() != QPixmapData::OpenVGClass || !d->affineTransform) {
+ if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) {
QPaintEngineEx::drawPixmapFragments(drawingData, dataCount, pixmap, hints);
return;
}
@@ -3416,7 +3390,7 @@ void QVGPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
// If we are not using a simple transform, then fall back
// to the default Qt path stroking algorithm.
- if (!d->affineTransform) {
+ if (!d->simpleTransform) {
QPaintEngineEx::drawTextItem(p, textItem);
return;
}
diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro
index 7a6fdf8..ac11188 100644
--- a/src/plugins/phonon/mmf/mmf.pro
+++ b/src/plugins/phonon/mmf/mmf.pro
@@ -75,25 +75,37 @@ symbian {
$$PHONON_MMF_DIR/utils.cpp \
$$PHONON_MMF_DIR/videowidget.cpp
- # Test for whether the build environment supports video rendering to graphics
- # surfaces.
- symbian:exists($${EPOCROOT}epoc32/include/platform/videoplayer2.h) {
- HEADERS += \
- $$PHONON_MMF_DIR/videooutput_surface.h \
- $$PHONON_MMF_DIR/videoplayer_surface.h
- SOURCES += \
- $$PHONON_MMF_DIR/videooutput_surface.cpp \
- $$PHONON_MMF_DIR/videoplayer_surface.cpp
- DEFINES += PHONON_MMF_VIDEO_SURFACES
- } else {
- HEADERS += \
- $$PHONON_MMF_DIR/ancestormovemonitor.h \
- $$PHONON_MMF_DIR/videooutput_dsa.h \
- $$PHONON_MMF_DIR/videoplayer_dsa.h
- SOURCES += \
- $$PHONON_MMF_DIR/ancestormovemonitor.cpp \
- $$PHONON_MMF_DIR/videooutput_dsa.cpp \
- $$PHONON_MMF_DIR/videoplayer_dsa.cpp \
+ symbian {
+ # Test for whether the build environment supports video rendering to graphics
+ # surfaces.
+ exists($${EPOCROOT}epoc32/include/platform/videoplayer2.h) {
+ HEADERS += \
+ $$PHONON_MMF_DIR/videooutput_surface.h \
+ $$PHONON_MMF_DIR/videoplayer_surface.h
+ SOURCES += \
+ $$PHONON_MMF_DIR/videooutput_surface.cpp \
+ $$PHONON_MMF_DIR/videoplayer_surface.cpp
+ DEFINES += PHONON_MMF_VIDEO_SURFACES
+ } else {
+ HEADERS += \
+ $$PHONON_MMF_DIR/ancestormovemonitor.h \
+ $$PHONON_MMF_DIR/videooutput_dsa.h \
+ $$PHONON_MMF_DIR/videoplayer_dsa.h
+ SOURCES += \
+ $$PHONON_MMF_DIR/ancestormovemonitor.cpp \
+ $$PHONON_MMF_DIR/videooutput_dsa.cpp \
+ $$PHONON_MMF_DIR/videoplayer_dsa.cpp \
+ }
+
+ # Test whether the build environment includes support for the Download Manager
+ # API, required for Progressive Download
+ exists($${EPOCROOT}epoc32/include/downloadmgrclient.h) | \
+ exists($${EPOCROOT}epoc32/include/mw/downloadmgrclient.h) {
+ HEADERS += $$PHONON_MMF_DIR/download.h
+ SOURCES += $$PHONON_MMF_DIR/download.cpp
+ LIBS += -ldownloadmgr
+ DEFINES += PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ }
}
LIBS += -lcone
diff --git a/src/qbase.pri b/src/qbase.pri
index b431ade..e565e4a 100644
--- a/src/qbase.pri
+++ b/src/qbase.pri
@@ -185,18 +185,21 @@ include(qt_targets.pri)
win32:DEFINES+=_USE_MATH_DEFINES
symbian {
- # Partial upgrade SIS file
- vendorinfo = \
- "; Localised Vendor name" \
- "%{\"Nokia, Qt\"}" \
- " " \
- "; Unique Vendor name" \
- ":\"Nokia, Qt\"" \
- " "
- pu_header = "; Partial upgrade package for testing $${TARGET} changes without reinstalling everything" \
- "$${LITERAL_HASH}{\"$${TARGET}\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU"
- partial_upgrade.pkg_prerules = pu_header vendorinfo
- partial_upgrade.sources = $$QMAKE_LIBDIR_QT/$${TARGET}.dll
- partial_upgrade.path = c:/sys/bin
- DEPLOYMENT += partial_upgrade
+ # Make partial upgrade SIS file for all dll's except webkit
+ !contains(TARGET.UID3, 0x200267C2):!contains(TARGET.UID3, 0xE00267C2) {
+ # Partial upgrade SIS file
+ vendorinfo = \
+ "; Localised Vendor name" \
+ "%{\"Nokia, Qt\"}" \
+ " " \
+ "; Unique Vendor name" \
+ ":\"Nokia, Qt\"" \
+ " "
+ pu_header = "; Partial upgrade package for testing $${TARGET} changes without reinstalling everything" \
+ "$${LITERAL_HASH}{\"$${TARGET}\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU"
+ partial_upgrade.pkg_prerules = pu_header vendorinfo
+ partial_upgrade.sources = $$QMAKE_LIBDIR_QT/$${TARGET}.dll
+ partial_upgrade.path = c:/sys/bin
+ DEPLOYMENT += partial_upgrade
+ }
}
diff --git a/src/src.pro b/src/src.pro
index 9a8b70fc..060f48b 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -119,7 +119,10 @@ src_webkit_declarative.target = sub-webkitdeclarative
src_webkit.depends = src_gui src_sql src_network
contains(QT_CONFIG, xmlpatterns): src_webkit.depends += src_xmlpatterns
src_imports.depends += src_webkit
- exists($$QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro): src_webkit.depends += src_javascriptcore
+ exists($$QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro) {
+ src_webkit.depends += src_javascriptcore
+ src_javascriptcore.depends = src_corelib
+ }
}
contains(QT_CONFIG, qt3support): src_plugins.depends += src_qt3support
contains(QT_CONFIG, dbus):{
diff --git a/tests/auto/qglthreads/tst_qglthreads.cpp b/tests/auto/qglthreads/tst_qglthreads.cpp
index cce3161..06131bd 100644
--- a/tests/auto/qglthreads/tst_qglthreads.cpp
+++ b/tests/auto/qglthreads/tst_qglthreads.cpp
@@ -49,6 +49,10 @@
#include <private/qt_x11_p.h>
#endif
+#ifdef Q_OS_SYMBIAN
+#include <unistd.h> // for usleep
+#endif
+
#define RUNNING_TIME 5000
tst_QGLThreads::tst_QGLThreads(QObject *parent)
@@ -209,6 +213,7 @@ public:
p.drawText(image.rect(), Qt::AlignCenter, "This is an autotest");
p.end();
m_gl->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption);
+
createdAndUploaded(image);
}
}