diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-10-07 14:12:04 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-10-07 14:12:04 (GMT) |
commit | 5f8ef6ac44e1db842003deeed6525eea70d8d83d (patch) | |
tree | 2b67b2abe7038e97fc72967a4882bf15c38d39a1 /src | |
parent | d7dd967d4a4775e70d270dbcd0623ef07128d420 (diff) | |
parent | 62a2fe9092d3b6038a08f5c5a7faa4a863b84fdc (diff) | |
download | Qt-5f8ef6ac44e1db842003deeed6525eea70d8d83d.zip Qt-5f8ef6ac44e1db842003deeed6525eea70d8d83d.tar.gz Qt-5f8ef6ac44e1db842003deeed6525eea70d8d83d.tar.bz2 |
Merge remote branch 'origin/4.7' into qt-master-from-4.7
Conflicts:
qmake/generators/win32/msbuild_objectmodel.cpp
qmake/generators/win32/msbuild_objectmodel.h
qmake/generators/win32/msvc_objectmodel.cpp
qmake/generators/win32/msvc_vcxproj.cpp
src/corelib/arch/qatomic_arm.h
tests/auto/qglthreads/tst_qglthreads.cpp
Diffstat (limited to 'src')
45 files changed, 1174 insertions, 404 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog index fbaf5d2..fd6c3f7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog +++ b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog @@ -1,3 +1,24 @@ +2010-08-24 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Don't seed the JS random number generator from time() + https://bugs.webkit.org/show_bug.cgi?id=41868 + <rdar://problem/8171025> + + Switch to using the secure random number generator to + seed the fast random generator, and make the generator + be per global object. + + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData): + (JSC::JSGlobalObject::weakRandomNumber): + * runtime/MathObject.cpp: + (JSC::mathProtoFuncRandom): + 2010-06-18 Tucker Jay <jay.tucker@nokia.com> Reviewed by NOBODY (OOPS!). @@ -94,6 +115,16 @@ * wtf/Platform.h: +2010-05-06 Fumitoshi Ukai <ukai@chromium.org> + + Reviewed by Alexey Proskuryakov. + + JavaScriptCore/wtf/RandomNumber.h should provide using WTF::* + https://bugs.webkit.org/show_bug.cgi?id=38719 + + * wtf/RandomNumber.h: + Add using directives. + 2010-04-28 Simon Hausmann <simon.hausmann@nokia.com>, Kent Hansen <kent.hansen@nokia.com> Reviewed by Darin Adler. diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp index 34b5f82..1c25c16 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp @@ -144,7 +144,6 @@ JSGlobalData::JSGlobalData(bool isShared) , firstStringifierToMark(0) , markStack(jsArrayVPtr) , cachedUTCOffset(NaN) - , weakRandom(static_cast<int>(currentTime())) #ifndef NDEBUG , mainThreadOnly(false) #endif diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h index 49a6c4c..dcd3289 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h @@ -184,8 +184,6 @@ namespace JSC { UString cachedDateString; double cachedDateStringValue; - - WeakRandom weakRandom; #ifndef NDEBUG bool mainThreadOnly; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h index 340e04d..7c20272 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h @@ -31,6 +31,7 @@ #include "StructureChain.h" #include <wtf/HashSet.h> #include <wtf/OwnPtr.h> +#include <wtf/RandomNumber.h> namespace JSC { @@ -91,6 +92,7 @@ namespace JSC { , datePrototype(0) , regExpPrototype(0) , methodCallDummy(0) + , weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0))) { } @@ -154,6 +156,7 @@ namespace JSC { RefPtr<JSGlobalData> globalData; HashSet<GlobalCodeBlock*> codeBlocks; + WeakRandom weakRandom; }; public: @@ -271,6 +274,7 @@ namespace JSC { return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); } + double weakRandomNumber() { return d()->weakRandom.get(); } protected: static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp index 8f22fba..807cfe7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp @@ -210,7 +210,7 @@ JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec, JSObject*, JSValue, cons JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, const ArgList&) { - return jsDoubleNumber(exec, exec->globalData().weakRandom.get()); + return jsDoubleNumber(exec, exec->lexicalGlobalObject()->weakRandomNumber()); } JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, const ArgList& args) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.h index fe1687c..e54e9ae 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.h @@ -39,4 +39,7 @@ namespace WTF { } +using WTF::randomNumber; +using WTF::weakRandomNumber; + #endif diff --git a/src/3rdparty/javascriptcore/VERSION b/src/3rdparty/javascriptcore/VERSION index 6f5fb7c..9991ac0 100644 --- a/src/3rdparty/javascriptcore/VERSION +++ b/src/3rdparty/javascriptcore/VERSION @@ -4,8 +4,8 @@ This is a snapshot of JavaScriptCore from The commit imported was from the - javascriptcore-snapshot-28062010 branch/tag + javascriptcore-snapshot-05102010 branch/tag and has the sha1 checksum - 0fccd26d3624e80cf68873701ef70ad72ca66bec + 82ead85cfea5859044eeb25b33314dcc0fa5eea1 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/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 137da0e..2bc33d3 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2772,7 +2772,7 @@ \value ElideNone Ellipsis should NOT appear in the text. Qt::ElideMiddle is normally the most appropriate choice for URLs (e.g., - "\l{http://qt.nokia.com/careers/movingto/brisbane/}{http://qt.nok...ovingto/brisbane/}"), + "\l{http://bugreports.qt.nokia.com/browse/QTWEBSITE-13}{http://bugreports.qt.../QTWEBSITE-13/}"), whereas Qt::ElideRight is appropriate for other strings (e.g., "\l{http://qt.nokia.com/doc/qq/qq09-mac-deployment.html}{Deploying Applications on Ma...}"). diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 6c1b6e7..983d249 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -582,48 +582,65 @@ QT_BEGIN_INCLUDE_NAMESPACE #include <stdlib.h> // for RAND_MAX QT_END_INCLUDE_NAMESPACE +#if !defined(QT_BOOTSTRAPPED) && defined(Q_OS_UNIX) +Q_GLOBAL_STATIC(QThreadStorage<QFile *>, devUrandomStorage); +#endif + QUuid QUuid::createUuid() { QUuid result; uint *data = &(result.data1); -#ifdef Q_OS_UNIX - QFile devUrandom; - devUrandom.setFileName(QLatin1String("/dev/urandom")); - if (devUrandom.open(QIODevice::ReadOnly)) { - qint64 numToRead = 4 * sizeof(uint); - devUrandom.read((char *) data, numToRead); // should read 128-bits of data +#if defined(Q_OS_UNIX) + QFile *devUrandom; +# if !defined(QT_BOOTSTRAPPED) + devUrandom = devUrandomStorage()->localData(); + if (!devUrandom) { + devUrandom = new QFile(QLatin1String("/dev/urandom")); + devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered); + devUrandomStorage()->setLocalData(devUrandom); + } +# else + QFile file(QLatin1String("/dev/urandom")); + devUrandom = &file; + devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered); +# endif + enum { AmountToRead = 4 * sizeof(uint) }; + if (devUrandom->isOpen() + && devUrandom->read((char *) data, AmountToRead) == AmountToRead) { + // we got what we wanted, nothing more to do + ; } else #endif { static const int intbits = sizeof(int)*8; static int randbits = 0; if (!randbits) { - int r = 0; + int r = 0; int max = RAND_MAX; do { ++r; } while ((max=max>>1)); randbits = r; } - // Seed the PRNG once per thread with a combination of current time, a - // stack address and a serial counter (since thread stack addresses are - // re-used). + // Seed the PRNG once per thread with a combination of current time, a + // stack address and a serial counter (since thread stack addresses are + // re-used). #ifndef QT_BOOTSTRAPPED - static QThreadStorage<int *> uuidseed; - if (!uuidseed.hasLocalData()) - { - int *pseed = new int; - static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); - qsrand(*pseed = QDateTime::currentDateTime().toTime_t() - + quintptr(&pseed) - + serial.fetchAndAddRelaxed(1)); - uuidseed.setLocalData(pseed); - } + static QThreadStorage<int *> uuidseed; + if (!uuidseed.hasLocalData()) + { + int *pseed = new int; + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); + qsrand(*pseed = QDateTime::currentDateTime().toTime_t() + + quintptr(&pseed) + + serial.fetchAndAddRelaxed(1)); + uuidseed.setLocalData(pseed); + } #else - static bool seeded = false; - if (!seeded) - qsrand(QDateTime::currentDateTime().toTime_t() - + quintptr(&seeded)); + static bool seeded = false; + if (!seeded) + qsrand(QDateTime::currentDateTime().toTime_t() + + quintptr(&seeded)); #endif int chunks = 16 / sizeof(uint); @@ -631,7 +648,7 @@ QUuid QUuid::createUuid() uint randNumber = 0; for (int filled = 0; filled < intbits; filled += randbits) randNumber |= qrand()<<filled; - *(data+chunks) = randNumber; + *(data+chunks) = randNumber; } } diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp index 88d73cc..2fc04f5 100644 --- a/src/corelib/thread/qthreadstorage.cpp +++ b/src/corelib/thread/qthreadstorage.cpp @@ -79,6 +79,21 @@ QThreadStorageData::QThreadStorageData(void (*func)(void *)) { QMutexLocker locker(mutex()); DestructorMap *destr = destructors(); + if (!destr) { + /* + the destructors vector has already been destroyed, yet a new + QThreadStorage is being allocated. this can only happen during global + destruction, at which point we assume that there is only one thread. + in order to keep QThreadStorage working, we need somewhere to store + the data, best place we have in this situation is at the tail of the + current thread's tls vector. the destructor is ignored, since we have + no where to store it, and no way to actually call it. + */ + QThreadData *data = QThreadData::current(); + id = data->tls.count(); + DEBUG_MSG("QThreadStorageData: Allocated id %d, destructor %p cannot be stored", id, func); + return; + } for (id = 0; id < destr->count(); id++) { if (destr->at(id) == 0) break; @@ -139,13 +154,15 @@ void **QThreadStorageData::set(void *p) data->thread); QMutexLocker locker(mutex()); - void (*destructor)(void *) = destructors()->value(id); + DestructorMap *destr = destructors(); + void (*destructor)(void *) = destr ? destr->value(id) : 0; locker.unlock(); void *q = value; value = 0; - destructor(q); + if (destructor) + destructor(q); } // store new data diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index a0df065..7a26c4f 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -74,10 +74,6 @@ int qFindString(const QChar *haystack, int haystackLen, int from, #define RXERR_INTERVAL QT_TRANSLATE_NOOP("QRegExp", "invalid interval") #define RXERR_CATEGORY QT_TRANSLATE_NOOP("QRegExp", "invalid category") -/* - WARNING! Be sure to read qregexp.tex before modifying this file. -*/ - /*! \class QRegExp \reentrant diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b4c6f57..cfffc4a 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -577,7 +577,7 @@ const QString::Null QString::null = { }; and join a list of strings into a single string with an optional separator using QStringList::join(). You can obtain a list of strings from a string list that contain a particular substring or - that match a particular QRegExp using the QStringList::find() + that match a particular QRegExp using the QStringList::filter() function. : \section1 Querying String Data diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index dc4ddbf..ad44d21 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -152,18 +152,12 @@ void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible) if (backingStore.data()) { backingStore.registerWidget(widget); } else { -#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS - S60->wsSession().SendEffectCommand(ETfxCmdRestoreLayer); -#endif backingStore.create(window); backingStore.registerWidget(widget); qt_widget_private(widget)->invalidateBuffer(widget->rect()); widget->repaint(); } } else { -#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS - S60->wsSession().SendEffectCommand(ETfxCmdDeallocateLayer); -#endif backingStore.unregisterWidget(widget); // In order to ensure that any resources used by the window surface // are immediately freed, we flush the WSERV command buffer. diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp index 4b75f0a..55548ef 100644 --- a/src/gui/kernel/qclipboard_x11.cpp +++ b/src/gui/kernel/qclipboard_x11.cpp @@ -595,7 +595,7 @@ static inline int maxSelectionIncr(Display *dpy) { return XMaxRequestSize(dpy) > 65536 ? 65536*4 : XMaxRequestSize(dpy)*4 - 100; } bool QX11Data::clipboardReadProperty(Window win, Atom property, bool deleteProperty, - QByteArray *buffer, int *size, Atom *type, int *format, bool nullterm) + QByteArray *buffer, int *size, Atom *type, int *format) { int maxsize = maxSelectionIncr(display); ulong bytes_left; // bytes_after @@ -641,13 +641,13 @@ bool QX11Data::clipboardReadProperty(Window win, Atom property, bool deletePrope break; } - int newSize = proplen + (nullterm ? 1 : 0); + int newSize = proplen; buffer->resize(newSize); bool ok = (buffer->size() == newSize); VDEBUG("QClipboard: read_property(): buffer resized to %d", buffer->size()); - if (ok) { + if (ok && newSize) { // could allocate buffer while (bytes_left) { @@ -683,23 +683,19 @@ bool QX11Data::clipboardReadProperty(Window win, Atom property, bool deletePrope XTextProperty textprop; textprop.encoding = *type; textprop.format = *format; - textprop.nitems = length; + textprop.nitems = buffer_offset; textprop.value = (unsigned char *) buffer->data(); char **list_ret = 0; int count; if (XmbTextPropertyToTextList(display, &textprop, &list_ret, &count) == Success && count && list_ret) { - offset = strlen(list_ret[0]); - buffer->resize(offset + (nullterm ? 1 : 0)); + offset = buffer_offset = strlen(list_ret[0]); + buffer->resize(offset); memcpy(buffer->data(), list_ret[0], offset); } if (list_ret) XFreeStringList(list_ret); } - - // zero-terminate (for text) - if (nullterm) - buffer->data()[buffer_offset] = '\0'; } // correct size, not 0-term. @@ -742,7 +738,7 @@ QByteArray QX11Data::clipboardReadIncrementalProperty(Window win, Atom property, if (event.xproperty.atom != property || event.xproperty.state != PropertyNewValue) continue; - if (X11->clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0, false)) { + if (X11->clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0)) { if (length == 0) { // no more data, we're done if (nullterm) { buf.resize(offset+1); @@ -836,7 +832,7 @@ static Atom send_selection(QClipboardData *d, Atom target, Window window, Atom p ATOM(INCR), 32, PropModeReplace, (uchar *) &bytes, 1); (void)new QClipboardINCRTransaction(window, property, atomFormat, dataFormat, data, increment); - return ATOM(INCR); + return property; } // make sure we can perform the XChangeProperty in a single request @@ -1070,7 +1066,7 @@ bool QClipboard::event(QEvent *e) QByteArray multi_data; if (req->property == XNone || !X11->clipboardReadProperty(req->requestor, req->property, false, &multi_data, - 0, &multi_type, &multi_format, 0) + 0, &multi_type, &multi_format) || multi_format != 32) { // MULTIPLE property not formatted correctly XSendEvent(dpy, req->requestor, False, NoEventMask, &event); @@ -1292,7 +1288,7 @@ QByteArray QClipboardWatcher::getDataInFormat(Atom fmtatom) const Atom type; XSelectInput(dpy, win, PropertyChangeMask); - if (X11->clipboardReadProperty(win, ATOM(_QT_SELECTION), true, &buf, 0, &type, 0, false)) { + if (X11->clipboardReadProperty(win, ATOM(_QT_SELECTION), true, &buf, 0, &type, 0)) { if (type == ATOM(INCR)) { int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0; buf = X11->clipboardReadIncrementalProperty(win, ATOM(_QT_SELECTION), nbytes, false); diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp index 92dd0a1..68d7688 100644 --- a/src/gui/kernel/qdnd_x11.cpp +++ b/src/gui/kernel/qdnd_x11.cpp @@ -1887,7 +1887,7 @@ static QVariant xdndObtainData(const char *format, QVariant::Type requestedType) if (got) { Atom type; - if (X11->clipboardReadProperty(tw->effectiveWinId(), ATOM(XdndSelection), true, &result, 0, &type, 0, false)) { + if (X11->clipboardReadProperty(tw->effectiveWinId(), ATOM(XdndSelection), true, &result, 0, &type, 0)) { if (type == ATOM(INCR)) { int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0; result = X11->clipboardReadIncrementalProperty(tw->effectiveWinId(), ATOM(XdndSelection), nbytes, false); diff --git a/src/gui/kernel/qmotifdnd_x11.cpp b/src/gui/kernel/qmotifdnd_x11.cpp index 0a7b350..3334455 100644 --- a/src/gui/kernel/qmotifdnd_x11.cpp +++ b/src/gui/kernel/qmotifdnd_x11.cpp @@ -766,7 +766,7 @@ QVariant QX11Data::motifdndObtainData(const char *mimeType) if (got) { Atom type; - if (X11->clipboardReadProperty(tw->internalWinId(), Dnd_selection, true, &result, 0, &type, 0, false)) { + if (X11->clipboardReadProperty(tw->internalWinId(), Dnd_selection, true, &result, 0, &type, 0)) { } } diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index 7383382..d62d9c3 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -350,7 +350,7 @@ struct QX11Data // from qclipboard_x11.cpp bool clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout); bool clipboardReadProperty(Window win, Atom property, bool deleteProperty, - QByteArray *buffer, int *size, Atom *type, int *format, bool nullterm); + QByteArray *buffer, int *size, Atom *type, int *format); QByteArray clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm); // from qdnd_x11.cpp diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 8d80e10..9085e98 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -1933,20 +1933,27 @@ void QWidgetPrivate::show_sys() if (flags & Qt::WindowStaysOnTopHint) { if (flags & Qt::WindowStaysOnBottomHint) qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time"; - netWmState.append(ATOM(_NET_WM_STATE_ABOVE)); - netWmState.append(ATOM(_NET_WM_STATE_STAYS_ON_TOP)); + if (!netWmState.contains(ATOM(_NET_WM_STATE_ABOVE))) + netWmState.append(ATOM(_NET_WM_STATE_ABOVE)); + if (!netWmState.contains(ATOM(_NET_WM_STATE_STAYS_ON_TOP))) + netWmState.append(ATOM(_NET_WM_STATE_STAYS_ON_TOP)); } else if (flags & Qt::WindowStaysOnBottomHint) { - netWmState.append(ATOM(_NET_WM_STATE_BELOW)); + if (!netWmState.contains(ATOM(_NET_WM_STATE_BELOW))) + netWmState.append(ATOM(_NET_WM_STATE_BELOW)); } if (q->isFullScreen()) { - netWmState.append(ATOM(_NET_WM_STATE_FULLSCREEN)); + if (!netWmState.contains(ATOM(_NET_WM_STATE_FULLSCREEN))) + netWmState.append(ATOM(_NET_WM_STATE_FULLSCREEN)); } if (q->isMaximized()) { - netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)); - netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)); + if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))) + netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)); + if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))) + netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)); } if (data.window_modality != Qt::NonModal) { - netWmState.append(ATOM(_NET_WM_STATE_MODAL)); + if (!netWmState.contains(ATOM(_NET_WM_STATE_MODAL))) + netWmState.append(ATOM(_NET_WM_STATE_MODAL)); } if (!netWmState.isEmpty()) { diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index c5429dd..9cc64b3 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -225,9 +225,8 @@ QPalette QGtkStyle::standardPalette() const GtkStyle *style = d->gtkStyle(); GtkWidget *gtkButton = d->gtkWidget("GtkButton"); GtkWidget *gtkEntry = d->getTextColorWidget(); - - GdkColor gdkBg, gdkBase, gdkText, gdkForeground, gdkSbg, gdkSfg; - QColor bg, base, text, fg, highlight, highlightText; + GdkColor gdkBg, gdkBase, gdkText, gdkForeground, gdkSbg, gdkSfg, gdkaSbg, gdkaSfg; + QColor bg, base, text, fg, highlight, highlightText, inactiveHighlight, inactiveHighlightedTExt; gdkBg = style->bg[GTK_STATE_NORMAL]; gdkForeground = gtkButton->style->fg[GTK_STATE_NORMAL]; @@ -237,14 +236,23 @@ QPalette QGtkStyle::standardPalette() const gdkText = gtkEntry->style->text[GTK_STATE_NORMAL]; gdkSbg = gtkEntry->style->base[GTK_STATE_SELECTED]; gdkSfg = gtkEntry->style->text[GTK_STATE_SELECTED]; + + // The ACTIVE base color is really used for inactive windows + gdkaSbg = gtkEntry->style->base[GTK_STATE_ACTIVE]; + gdkaSfg = gtkEntry->style->text[GTK_STATE_ACTIVE]; + bg = QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8); text = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8); fg = QColor(gdkForeground.red>>8, gdkForeground.green>>8, gdkForeground.blue>>8); base = QColor(gdkBase.red>>8, gdkBase.green>>8, gdkBase.blue>>8); highlight = QColor(gdkSbg.red>>8, gdkSbg.green>>8, gdkSbg.blue>>8); highlightText = QColor(gdkSfg.red>>8, gdkSfg.green>>8, gdkSfg.blue>>8); + inactiveHighlight = QColor(gdkaSbg.red>>8, gdkaSbg.green>>8, gdkaSbg.blue>>8); + inactiveHighlightedTExt = QColor(gdkaSfg.red>>8, gdkaSfg.green>>8, gdkaSfg.blue>>8); palette.setColor(QPalette::HighlightedText, highlightText); + + palette.setColor(QPalette::Light, bg.lighter(125)); palette.setColor(QPalette::Shadow, bg.darker(130)); palette.setColor(QPalette::Dark, bg.darker(120)); @@ -279,6 +287,10 @@ QPalette QGtkStyle::standardPalette() const highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha()); palette.setColor(QPalette::Disabled, QPalette::Highlight, highlight); palette.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText); + + palette.setColor(QPalette::Inactive, QPalette::HighlightedText, inactiveHighlightedTExt); + palette.setColor(QPalette::Inactive, QPalette::Highlight, inactiveHighlight); + style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow", d->gtk_window_get_type()); if (style) { @@ -791,10 +803,13 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, // ### this mess should move to subcontrolrect QRect frameRect = option->rect.adjusted(1, 1, -1, -2); - if (qobject_cast<const QTabBar*>(widget)) - frameRect.adjust(-1, 1, 1, 1); - - gtkPainter.paintFocus(NULL, "tab", frameRect, GTK_STATE_ACTIVE, style); + if (qobject_cast<const QTabBar*>(widget)) { + GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook"); + style = gtkPainter.getStyle(gtkNotebook); + gtkPainter.paintFocus(gtkNotebook, "tab", frameRect.adjusted(-1, 1, 1, 1), GTK_STATE_ACTIVE, style); + } else { + gtkPainter.paintFocus(NULL, "tab", frameRect, GTK_STATE_ACTIVE, style); + } } break; diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 556e0f3..3a05f40 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -3336,6 +3336,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter if (needText) { QPalette pal = tb->palette; QPalette::ColorRole role = QPalette::NoRole; + if (!proxy()->styleHint(SH_UnderlineShortcut, tb, w)) + alignment |= Qt::TextHideMnemonic; if (down) cr.translate(shiftX, shiftY); if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 @@ -3353,13 +3355,13 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter role = QPalette::HighlightedText; } } - drawItemText(p, cr, alignment, pal, - tb->state & State_Enabled, tb->text, role); + proxy()->drawItemText(p, cr, alignment, pal, + tb->state & State_Enabled, tb->text, role); if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5 && (tb->state & State_Sunken)) { // Draw a "drop shadow" in earlier versions. - drawItemText(p, cr.adjusted(0, 1, 0, 1), alignment, - tb->palette, tb->state & State_Enabled, tb->text); + proxy()->drawItemText(p, cr.adjusted(0, 1, 0, 1), alignment, + tb->palette, tb->state & State_Enabled, tb->text); } } } else { diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index cf7e963..89f54bc 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -106,8 +106,8 @@ const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** {5,0,-909,0,0,2,0,0,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1,106}, {5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106}, -{7,0,-909,0,0,2,0,0,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, -{7,0,-909,0,0,2,0,0,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, +{7,0,-909,0,0,2,0,0,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, +{7,0,-909,0,0,2,0,0,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, {7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106} // *** End of generated data *** }; @@ -2453,7 +2453,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti case PE_PanelItemViewRow: // ### Qt 5: remove #ifndef QT_NO_ITEMVIEWS if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { - if (QS60StylePrivate::equalToThemePalette(vopt->palette.base().texture().cacheKey(), QPalette::Base)) { + if (!QS60StylePrivate::equalToThemePalette(vopt->palette.base().texture().cacheKey(), QPalette::Base)) { //QPalette::Base has been changed, let commonstyle draw the item commonStyleDraws = true; } else { @@ -2530,11 +2530,6 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const //without having to define custom pixel metric metricValue *= 2; - if (widget && (metric == PM_FocusFrameHMargin)) - if (qobject_cast<const QTableView *>(widget)) - //Halve the focus frame margin for table items - metricValue /= 2; - return metricValue; } diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 6affa36..d717214 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -333,7 +333,7 @@ static QStringList findAllLibSsl() paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH")) .split(QLatin1Char(':'), QString::SkipEmptyParts); # endif - paths << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib"); + paths << QLatin1String("/lib") << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib"); QStringList foundSsls; foreach (const QString &path, paths) { diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 0941040..025731d 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..b839b00 100644 --- a/src/opengl/gl2paintengineex/qtriangulator.cpp +++ b/src/opengl/gl2paintengineex/qtriangulator.cpp @@ -57,6 +57,9 @@ #include <math.h> +#include <private/qgl_p.h> +#include <private/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 // //============================================================================// @@ -610,7 +625,7 @@ struct QRBTree // Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise. // 'left' and 'right' cannot be null. int order(Node *left, Node *right); - inline bool verify() const; + inline bool validate() const; private: void rotateLeft(Node *node); @@ -1023,7 +1038,7 @@ bool QRBTree<T>::checkRedBlackProperty(Node *top) const } template <class T> -inline bool QRBTree<T>::verify() const +inline bool QRBTree<T>::validate() const { return checkRedBlackProperty(root) && blackDepth(root) != -1; } @@ -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 ¢er = 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(); @@ -2799,7 +2854,7 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition() m_edges.at(j).node = node; m_edges.at(j).helper = i; m_edgeList.attachAfter(leftEdgeNode, node); - Q_ASSERT(m_edgeList.verify()); + Q_ASSERT(m_edgeList.validate()); } else { leftEdgeNode = searchEdgeLeftOfEdge(i); QRBTree<int>::Node *node = m_edgeList.newNode(); @@ -2807,7 +2862,7 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition() m_edges.at(i).node = node; m_edges.at(i).helper = i; m_edgeList.attachAfter(leftEdgeNode, node); - Q_ASSERT(m_edgeList.verify()); + Q_ASSERT(m_edgeList.validate()); } break; case MergeVertex: @@ -2826,7 +2881,7 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition() diagonals.add(QPair<int, int>(i, m_edges.at(i).helper)); if (m_edges.at(i).node) { m_edgeList.deleteNode(m_edges.at(i).node); - Q_ASSERT(m_edgeList.verify()); + Q_ASSERT(m_edgeList.validate()); } else { qWarning("Inconsistent polygon. (#5)"); } @@ -2835,7 +2890,7 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition() diagonals.add(QPair<int, int>(i, m_edges.at(j).helper)); if (m_edges.at(j).node) { m_edgeList.deleteNode(m_edges.at(j).node); - Q_ASSERT(m_edgeList.verify()); + Q_ASSERT(m_edgeList.validate()); } else { qWarning("Inconsistent polygon. (#6)"); } @@ -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 6d7449d..bf1dbbc 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 Q_OPENGL_EXPORT qt_resolve_buffer_extensions(QGLContext *ctx); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index f98dcff..8157b2a 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -534,8 +534,9 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & } } #endif - if (d_ptr->paintedRegion.boundingRect() != geometry() && - hasPartialUpdateSupport()) { + if (hasPartialUpdateSupport() && + d_ptr->paintedRegion.boundingRect().width() * d_ptr->paintedRegion.boundingRect().height() < + geometry().width() * geometry().height() * 0.2) { context()->d_func()->swapRegion(&d_ptr->paintedRegion); } else context()->swapBuffers(); diff --git a/src/openvg/openvg.pro b/src/openvg/openvg.pro index eb60331..c05af90 100644 --- a/src/openvg/openvg.pro +++ b/src/openvg/openvg.pro @@ -35,7 +35,7 @@ contains(QT_CONFIG, egl) { } symbian { - DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING + DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING QVG_SCISSOR_CLIP SOURCES += \ qvg_symbian.cpp } 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 ®ion, 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 c61ed47..1e13149 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):{ |