From 55bf3ab3fb5591544e1f6a7996d5fdedb8e699c9 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 1 Oct 2010 11:25:02 +0300 Subject: Remove partial upgrade deployment generation for Webkit Generic partial upgrade package deployment generation in qbase.pri wrecks webkit pkg files. Reviewed-by: axis --- src/qbase.pri | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/qbase.pri b/src/qbase.pri index b431ade..e565e4a 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -185,18 +185,21 @@ include(qt_targets.pri) win32:DEFINES+=_USE_MATH_DEFINES symbian { - # Partial upgrade SIS file - vendorinfo = \ - "; Localised Vendor name" \ - "%{\"Nokia, Qt\"}" \ - " " \ - "; Unique Vendor name" \ - ":\"Nokia, Qt\"" \ - " " - pu_header = "; Partial upgrade package for testing $${TARGET} changes without reinstalling everything" \ - "$${LITERAL_HASH}{\"$${TARGET}\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU" - partial_upgrade.pkg_prerules = pu_header vendorinfo - partial_upgrade.sources = $$QMAKE_LIBDIR_QT/$${TARGET}.dll - partial_upgrade.path = c:/sys/bin - DEPLOYMENT += partial_upgrade + # Make partial upgrade SIS file for all dll's except webkit + !contains(TARGET.UID3, 0x200267C2):!contains(TARGET.UID3, 0xE00267C2) { + # Partial upgrade SIS file + vendorinfo = \ + "; Localised Vendor name" \ + "%{\"Nokia, Qt\"}" \ + " " \ + "; Unique Vendor name" \ + ":\"Nokia, Qt\"" \ + " " + pu_header = "; Partial upgrade package for testing $${TARGET} changes without reinstalling everything" \ + "$${LITERAL_HASH}{\"$${TARGET}\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU" + partial_upgrade.pkg_prerules = pu_header vendorinfo + partial_upgrade.sources = $$QMAKE_LIBDIR_QT/$${TARGET}.dll + partial_upgrade.path = c:/sys/bin + DEPLOYMENT += partial_upgrade + } } -- cgit v0.12 From 1f14df23bf0e593c31efc846c13f11afb0fad6b8 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 28 Sep 2010 11:01:20 +0100 Subject: Progressive download in Phonon MMF backend: added download managers This patch adds a Download class which uses the RHttpDownloadMgr API to download a media clip over HTTP. Task-number: QTBUG-10769 Reviewed-by: Derick Hawcroft --- src/3rdparty/phonon/mmf/download.cpp | 194 +++++++++++++++++++++++++++++++++++ src/3rdparty/phonon/mmf/download.h | 111 ++++++++++++++++++++ src/plugins/phonon/mmf/mmf.pro | 3 + 3 files changed, 308 insertions(+) create mode 100644 src/3rdparty/phonon/mmf/download.cpp create mode 100644 src/3rdparty/phonon/mmf/download.h 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 . + +*/ + +#include "download.h" +#include "utils.h" +#include +#include + +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(); + 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..b57348b --- /dev/null +++ b/src/3rdparty/phonon/mmf/download.h @@ -0,0 +1,111 @@ +/* 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 . + +*/ + +#ifndef PHONON_MMF_DOWNLOAD_H +#define PHONON_MMF_DOWNLOAD_H + +#include +#include +#include +#include + +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(); + + // Only has effect when QT_PHONON_MMF_DOWNLOAD_DUMMY is defined + 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/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro index 7a6fdf8..902354f 100644 --- a/src/plugins/phonon/mmf/mmf.pro +++ b/src/plugins/phonon/mmf/mmf.pro @@ -36,6 +36,7 @@ symbian { $$PHONON_MMF_DIR/backend.h \ $$PHONON_MMF_DIR/bassboost.h \ $$PHONON_MMF_DIR/defs.h \ + $$PHONON_MMF_DIR/download.h \ $$PHONON_MMF_DIR/dummyplayer.h \ $$PHONON_MMF_DIR/effectfactory.h \ $$PHONON_MMF_DIR/effectparameter.h \ @@ -61,6 +62,7 @@ symbian { $$PHONON_MMF_DIR/abstractvideoplayer.cpp \ $$PHONON_MMF_DIR/backend.cpp \ $$PHONON_MMF_DIR/bassboost.cpp \ + $$PHONON_MMF_DIR/download.cpp \ $$PHONON_MMF_DIR/dummyplayer.cpp \ $$PHONON_MMF_DIR/effectfactory.cpp \ $$PHONON_MMF_DIR/effectparameter.cpp \ @@ -111,6 +113,7 @@ symbian { LIBS += -lapgrfx -lapmime # For recognizer LIBS += -lmmfcontrollerframework # For CMMFMetaDataEntry LIBS += -lmediaclientaudiostream # For CMdaAudioOutputStream + LIBS += -ldownloadmgr # These are for effects. LIBS += -lAudioEqualizerEffect -lBassBoostEffect -lDistanceAttenuationEffect -lDopplerBase -lEffectBase -lEnvironmentalReverbEffect -lListenerDopplerEffect -lListenerLocationEffect -lListenerOrientationEffect -lLocationBase -lLoudnessEffect -lOrientationBase -lSourceDopplerEffect -lSourceLocationEffect -lSourceOrientationEffect -lStereoWideningEffect -- cgit v0.12 From 865a9214fbb858cd5089aa3073ad2cff305017ea Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 28 Sep 2010 11:05:41 +0100 Subject: Progressive download in Phonon MMF backend: integrated with player This commit integrates the Download class with the media playback classes in the backend, to implement Progressive Download. Note that this PDL implementation has one drawback: when video playback is paused due to shortage of data (i.e. due to the download being temporarily stalled), the display goes black. This is because, when the end of the currently-downloaded data is reached, the playback session is closed. When more data becomes available, the clip is re-opened, a seek is done to reach the previous playback position, and playback is re-started. Closing the playback session closes the video stack's connection to the display, thereby causing the video widget to go black while more data is buffered. This is a consequence of the level in the native video stack at which the Phonon integration is done: managing a network stall without requiring the playback session to be closed would require integration below the MMF client API, specifically at the MMF controller level. Task-number: QTBUG-10769 Reviewed-by: Derick Hawcroft --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 148 +++++++++++++++++++++--- src/3rdparty/phonon/mmf/abstractmediaplayer.h | 17 +++ src/3rdparty/phonon/mmf/abstractvideoplayer.cpp | 24 +++- src/3rdparty/phonon/mmf/abstractvideoplayer.h | 5 +- src/3rdparty/phonon/mmf/audioplayer.cpp | 18 ++- src/3rdparty/phonon/mmf/audioplayer.h | 5 +- src/3rdparty/phonon/mmf/mediaobject.cpp | 36 +++--- src/3rdparty/phonon/mmf/mediaobject.h | 1 + 8 files changed, 211 insertions(+), 43 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 3702560..a728423 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -51,10 +51,13 @@ 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) + , m_download(0) + , m_downloadStalled(false) { connect(m_positionTimer.data(), SIGNAL(timeout()), this, SLOT(positionTick())); connect(m_bufferStatusTimer.data(), SIGNAL(timeout()), this, SLOT(bufferStatusTick())); @@ -183,6 +186,7 @@ void MMF::AbstractMediaPlayer::seek(qint64 ms) } doSeek(ms); + m_position = ms; resetMarksIfRewound(); if(wasPlaying && state() != ErrorState) { @@ -207,6 +211,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,6 +256,14 @@ void MMF::AbstractMediaPlayer::open() symbianErr = openFile(*file); if (KErrNone != symbianErr) errorMessage = tr("Error opening file"); + } 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(); } else { symbianErr = openUrl(url.toString()); if (KErrNone != symbianErr) @@ -288,6 +305,14 @@ void MMF::AbstractMediaPlayer::open() TRACE_EXIT_0(); } +void MMF::AbstractMediaPlayer::close() +{ + doClose(); + delete m_download; + m_download = 0; + m_position = 0; +} + void MMF::AbstractMediaPlayer::volumeChanged(qreal volume) { TRACE_CONTEXT(AbstractMediaPlayer::volumeChanged, EAudioInternal); @@ -374,7 +399,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 +411,28 @@ 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(); + m_downloadStalled = false; + } } 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 +456,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 +470,28 @@ qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds return in.Int64() / 1000; } +bool MMF::AbstractMediaPlayer::isProgressiveDownload() const +{ + return (0 != m_download); +} + +bool MMF::AbstractMediaPlayer::progressiveDownloadStalled() const +{ + return m_downloadStalled; +} + //----------------------------------------------------------------------------- // 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 +516,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,9 +545,71 @@ void MMF::AbstractMediaPlayer::startPlayback() changeState(PlayingState); } +void MMF::AbstractMediaPlayer::setProgressiveDownloadStalled() +{ + 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(); +#ifdef QT_PHONON_MMF_DOWNLOAD_DUMMY + 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); +} + +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; + } } 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..99fc101 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -23,6 +23,7 @@ along with this library. If not, see . #include #include #include "abstractplayer.h" +#include "download.h" class RFile; @@ -48,6 +49,7 @@ protected: public: virtual void open(); + virtual void close(); // MediaObjectInterface virtual void play(); @@ -55,6 +57,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 +71,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 metaDataEntry(int index) const = 0; @@ -86,6 +92,9 @@ protected: static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &); + bool isProgressiveDownload() const; + bool progressiveDownloadStalled() const; + private: void startPositionTimer(); void stopPositionTimer(); @@ -96,6 +105,7 @@ private: void emitMarksIfReached(qint64 position); void resetMarksIfRewound(); void startPlayback(); + void setProgressiveDownloadStalled(); enum Pending { NothingPending, @@ -108,6 +118,8 @@ private: private Q_SLOTS: void positionTick(); void bufferStatusTick(); + void downloadLengthChanged(qint64); + void downloadStateChanged(Download::State); private: MediaObject *const m_parent; @@ -115,6 +127,7 @@ private: Pending m_pending; QScopedPointer m_positionTimer; + qint64 m_position; QScopedPointer m_bufferStatusTimer; PrivateState m_stateBeforeBuffering; @@ -127,6 +140,10 @@ private: // Used for playback of resource files TPtrC8 m_buffer; + // Used for progressive download + Download *m_download; + bool m_downloadStalled; + QMultiMap 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 . */ +#include #include #include #include @@ -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 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 . */ +#include #include #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 metaDataEntry(int index) const; 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; -- cgit v0.12 From bd53ef2094a020789e9543156c524cd90a2d5302 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Mon, 27 Sep 2010 18:07:35 +0100 Subject: qmediaplayer: show buffer status of 0% During progressive download, it is not possible for the Symbian MMF Phonon backend to determine the buffering status, so it returns a value of 0%. This change causes qmediaplayer to display this value in the UI, thereby giving a visible notification of buffering during progressive download. Task-number: QTBUG-10769 Reviewed-by: Derick Hawcroft --- demos/qmediaplayer/mediaplayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index 3cb0616..97a8e35 100644 --- a/demos/qmediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp @@ -716,7 +716,7 @@ void MediaPlayer::openFile() void MediaPlayer::bufferStatus(int percent) { - if (percent == 0 || percent == 100) + if (percent == 100) progressLabel->setText(QString()); else { QString str = QString::fromLatin1("(%1%)").arg(percent); -- cgit v0.12 From c168be1aa3dc4f7ccc70d530244fc97af0b4d1e1 Mon Sep 17 00:00:00 2001 From: mread Date: Fri, 1 Oct 2010 13:13:42 +0100 Subject: fixed hybrid heap Symbian udeb build issues Fixed name collision with TAllocFail Added definition for EDebugHdrSize and fixed scope issue Added definition for SRAllocatorBurstFail Added a definition for global enum ETHeapBadDebugFailParameter Tested compilation on: Symbian^3 RnD - armv5_urel, armv5_udeb, winscw_urel, winscw_udeb S60 3.1 SDK - armv5_urel, armv5_udeb S60 5.0 SDK - armv5_urel, armv5_udeb Symbian^3 PDK - armv5_urel, armv5_udeb Symbian^4 RnD - armv5_urel, armv5_udeb Basic functional testing on N8 armv5_urel Task-number: QTBUG-14168 Reviewed-by: Shane Kearns --- src/corelib/arch/symbian/debugfunction.cpp | 2 +- src/corelib/arch/symbian/heap_hybrid_p.h | 6 +++++- src/corelib/arch/symbian/qt_hybridheap_symbian_p.h | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/corelib/arch/symbian/debugfunction.cpp b/src/corelib/arch/symbian/debugfunction.cpp index f3b5d2d..91f6917 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; } } 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..92cfe0e 100644 --- a/src/corelib/arch/symbian/qt_hybridheap_symbian_p.h +++ b/src/corelib/arch/symbian/qt_hybridheap_symbian_p.h @@ -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 { -- cgit v0.12 From d1b2480f33641055f2d729212addf059577a4e01 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Fri, 1 Oct 2010 15:33:37 +0100 Subject: Fixed crash on startup in Symbian debug build This fixes a typo in a debug-only function in the hybrid heap allocator. The typo causes an assertion to fail during startup of applications, when using a debug build of Qt. Reviewed-by: mread --- src/corelib/arch/symbian/debugfunction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/arch/symbian/debugfunction.cpp b/src/corelib/arch/symbian/debugfunction.cpp index 91f6917..31937e8 100644 --- a/src/corelib/arch/symbian/debugfunction.cpp +++ b/src/corelib/arch/symbian/debugfunction.cpp @@ -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 ) -- cgit v0.12 From 51d007e0fa699339f072956bbd8bfe33db9b7f70 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Sun, 3 Oct 2010 19:43:29 +0100 Subject: Added qmake check for presence of RHttpDownloadMgr header downloadmgrclient.h is not found on S^4 baselines, causing a build failure. This commit is a temporary workaround, which disables progressive download support if the header is not found. The correct solution is to determine whether the RHttpDownloadMgr definition has moved, and if so, to modify the .pro file to include the new path. Task-number: QTBUG-10769 Reviewed-by: TrustMe --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 26 ++++++++++-- src/3rdparty/phonon/mmf/abstractmediaplayer.h | 9 ++++- src/3rdparty/phonon/mmf/download.h | 2 - src/plugins/phonon/mmf/mmf.pro | 53 +++++++++++++++---------- 4 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index a728423..dfc5840 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -56,8 +56,10 @@ MMF::AbstractMediaPlayer::AbstractMediaPlayer , 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())); @@ -256,7 +258,9 @@ void MMF::AbstractMediaPlayer::open() symbianErr = openFile(*file); if (KErrNone != symbianErr) errorMessage = tr("Error opening file"); - } else if (url.scheme() == QLatin1String("http")) { + } +#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)), @@ -264,7 +268,9 @@ void MMF::AbstractMediaPlayer::open() connect(m_download, SIGNAL(stateChanged(Download::State)), this, SLOT(downloadStateChanged(Download::State))); m_download->start(); - } else { + } +#endif + else { symbianErr = openUrl(url.toString()); if (KErrNone != symbianErr) errorMessage = tr("Error opening URL"); @@ -308,8 +314,10 @@ void MMF::AbstractMediaPlayer::open() void MMF::AbstractMediaPlayer::close() { doClose(); +#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD delete m_download; m_download = 0; +#endif m_position = 0; } @@ -419,7 +427,9 @@ void MMF::AbstractMediaPlayer::loadingComplete(int error) bufferingComplete(); doSeek(m_position); startPlayback(); +#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD m_downloadStalled = false; +#endif } } else { Q_ASSERT(Phonon::LoadingState == state()); @@ -472,12 +482,20 @@ qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds 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 } //----------------------------------------------------------------------------- @@ -547,6 +565,7 @@ void MMF::AbstractMediaPlayer::startPlayback() void MMF::AbstractMediaPlayer::setProgressiveDownloadStalled() { +#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD TRACE_CONTEXT(AbstractMediaPlayer::setProgressiveDownloadStalled, EAudioApi); TRACE_ENTRY("state %d", state()); Q_ASSERT(isProgressiveDownload()); @@ -555,7 +574,6 @@ void MMF::AbstractMediaPlayer::setProgressiveDownloadStalled() bufferingStarted(); // Video player loses window handle when closed - need to reapply it here videoOutputChanged(); -#ifdef QT_PHONON_MMF_DOWNLOAD_DUMMY m_download->resume(); #endif } @@ -569,6 +587,7 @@ void MMF::AbstractMediaPlayer::bufferStatusTick() emit MMF::AbstractPlayer::bufferStatus(status); } +#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD void MMF::AbstractMediaPlayer::downloadLengthChanged(qint64 length) { TRACE_CONTEXT(AbstractMediaPlayer::downloadLengthChanged, EAudioApi); @@ -611,6 +630,7 @@ void MMF::AbstractMediaPlayer::downloadStateChanged(Download::State state) 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 99fc101..c3b4528 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -23,7 +23,9 @@ along with this library. If not, see . #include #include #include "abstractplayer.h" -#include "download.h" +#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD +# include "download.h" +#endif class RFile; @@ -118,8 +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; @@ -140,9 +144,10 @@ private: // Used for playback of resource files TPtrC8 m_buffer; - // Used for progressive download +#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD Download *m_download; bool m_downloadStalled; +#endif QMultiMap m_metaData; diff --git a/src/3rdparty/phonon/mmf/download.h b/src/3rdparty/phonon/mmf/download.h index b57348b..bda7963 100644 --- a/src/3rdparty/phonon/mmf/download.h +++ b/src/3rdparty/phonon/mmf/download.h @@ -70,8 +70,6 @@ public: const QUrl &sourceUrl() const; const QString &targetFileName() const; void start(); - - // Only has effect when QT_PHONON_MMF_DOWNLOAD_DUMMY is defined void resume(); enum State { diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro index 902354f..ac11188 100644 --- a/src/plugins/phonon/mmf/mmf.pro +++ b/src/plugins/phonon/mmf/mmf.pro @@ -36,7 +36,6 @@ symbian { $$PHONON_MMF_DIR/backend.h \ $$PHONON_MMF_DIR/bassboost.h \ $$PHONON_MMF_DIR/defs.h \ - $$PHONON_MMF_DIR/download.h \ $$PHONON_MMF_DIR/dummyplayer.h \ $$PHONON_MMF_DIR/effectfactory.h \ $$PHONON_MMF_DIR/effectparameter.h \ @@ -62,7 +61,6 @@ symbian { $$PHONON_MMF_DIR/abstractvideoplayer.cpp \ $$PHONON_MMF_DIR/backend.cpp \ $$PHONON_MMF_DIR/bassboost.cpp \ - $$PHONON_MMF_DIR/download.cpp \ $$PHONON_MMF_DIR/dummyplayer.cpp \ $$PHONON_MMF_DIR/effectfactory.cpp \ $$PHONON_MMF_DIR/effectparameter.cpp \ @@ -77,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 @@ -113,7 +123,6 @@ symbian { LIBS += -lapgrfx -lapmime # For recognizer LIBS += -lmmfcontrollerframework # For CMMFMetaDataEntry LIBS += -lmediaclientaudiostream # For CMdaAudioOutputStream - LIBS += -ldownloadmgr # These are for effects. LIBS += -lAudioEqualizerEffect -lBassBoostEffect -lDistanceAttenuationEffect -lDopplerBase -lEffectBase -lEnvironmentalReverbEffect -lListenerDopplerEffect -lListenerLocationEffect -lListenerOrientationEffect -lLocationBase -lLoudnessEffect -lOrientationBase -lSourceDopplerEffect -lSourceLocationEffect -lSourceOrientationEffect -lStereoWideningEffect -- cgit v0.12 From c2ed7b0cb9b9db105c650301af5bd3199cdd032e Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 4 Oct 2010 09:32:42 +0200 Subject: Got rid of "No such directory" warning when shadow building. RevBy: Thomas Zander --- configure | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 53f520a..f7904d9 100755 --- a/configure +++ b/configure @@ -4902,9 +4902,8 @@ case "$XPLATFORM" in *symbian*) # Raptor does not support configure tests. # the main commands needed to compile; - (cd config.tests/symbian - mkdir -p rcomp - cd rcomp + (mkdir -p config.tests/symbian/rcomp + cd config.tests/symbian/rcomp rm -f rcomp_test.rsg touch rcomp_test.rpp rcomp_test.rsc rcomp_test.rss rcomp -u -m045,046,047 -s./rcomp_test.rpp -o./rcomp_test.rsc -h./rcomp_test.rsg -i./rcomp_test.rss 2>&1 > /dev/null -- cgit v0.12 From 9dae9599c4d19ca55693df0b81bacbc1255ec733 Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 4 Oct 2010 09:33:20 +0200 Subject: Made scripttools disabled on Symbian by default, like on Windows. RevBy: Miikka Heikkinen --- configure | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/configure b/configure index f7904d9..aca3467 100755 --- a/configure +++ b/configure @@ -7224,7 +7224,14 @@ if [ "$CFG_SCRIPTTOOLS" = "yes" -a "$CFG_SCRIPT" = "no" ]; then exit 1 fi if [ "$CFG_SCRIPTTOOLS" = "auto" -a "$CFG_SCRIPT" != "no" ]; then - CFG_SCRIPTTOOLS="yes" + case "$XPLATFORM" in + symbian*) + CFG_SCRIPTTOOLS="no" + ;; + *) + CFG_SCRIPTTOOLS="yes" + ;; + esac elif [ "$CFG_SCRIPT" = "no" ]; then CFG_SCRIPTTOOLS="no" fi -- cgit v0.12 From 207d9239dc6b67109b5e8cbdea7e5a589c167e85 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Mon, 4 Oct 2010 10:55:11 +0300 Subject: Enable QtOpenGL vector path caching on Symbian/IVE3 IVE3 doesn't support UNSIGNED_INT index values in DrawElements. This patch checks if GL_OES_element_index_uint extensions is supported and determines DrawElement indices type based on that. On desktop environment UNSIGNED_INT is always supported. Task-number: QTBUG-13563 Reviewed-by: Gunnar --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 42 +-- src/opengl/gl2paintengineex/qtriangulator.cpp | 354 ++++++++++++++------- src/opengl/gl2paintengineex/qtriangulator_p.h | 58 +++- src/opengl/qglextensions_p.h | 14 + 4 files changed, 334 insertions(+), 134 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index a81ed8e..a98d7cc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -646,7 +646,7 @@ struct QGL2PEVectorPathCache GLuint ibo; #else float *vertices; - quint32 *indices; + void *indices; #endif int vertexCount; int indexCount; @@ -696,14 +696,6 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) const QPointF* const points = reinterpret_cast(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 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..ea072b4 100644 --- a/src/opengl/gl2paintengineex/qtriangulator.cpp +++ b/src/opengl/gl2paintengineex/qtriangulator.cpp @@ -57,6 +57,9 @@ #include +#include "qgl_p.h" +#include "qglextensions_p.h" + QT_BEGIN_NAMESPACE //#define Q_TRIANGULATOR_DEBUG @@ -185,6 +188,18 @@ sort_loop_end: sort(array + low + 1, count - low - 1); } +template +struct QVertexSet +{ + inline QVertexSet() { } + inline QVertexSet(const QVertexSet &other) : vertices(other.vertices), indices(other.indices) { } + QVertexSet &operator = (const QVertexSet &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 vertices; // [x[0], y[0], x[1], y[1], x[2], ...] + QVector indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...] +}; + //============================================================================// // QFraction // //============================================================================// @@ -1295,7 +1310,7 @@ inline void QRingBuffer::enqueue(const T &x) //============================================================================// // QTriangulator // //============================================================================// - +template class QTriangulator { public: @@ -1308,7 +1323,7 @@ public: class ComplexToSimple { public: - inline ComplexToSimple(QTriangulator *parent) : m_parent(parent), + inline ComplexToSimple(QTriangulator *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 *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::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 *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 *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 triangulate(); + QVertexSet polyline(); private: QDataBuffer m_vertices; - QVector m_indices; + QVector m_indices; uint m_hint; }; @@ -1517,7 +1532,8 @@ private: // QTriangulator // //============================================================================// -QTriangleSet QTriangulator::triangulate() +template +QVertexSet QTriangulator::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 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 +QVertexSet QTriangulator::polyline() { - QPolylineSet result; + QVertexSet 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 +void QTriangulator::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 +void QTriangulator::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 +void QTriangulator::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 +void QTriangulator::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 +void QTriangulator::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 +bool QTriangulator::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 +bool QTriangulator::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::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const +template +QRBTree::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const { QRBTree::Node *current = m_edgeList.root; QRBTree::Node *result = 0; @@ -1767,7 +1791,8 @@ QRBTree::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeInd return result; } -QRBTree::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree::Node *after) const +template +QRBTree::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree::Node *after) const { if (!m_edgeList.root) return after; @@ -1782,7 +1807,8 @@ QRBTree::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeInd return result; } -QPair::Node *, QRBTree::Node *> QTriangulator::ComplexToSimple::bounds(const QPodPoint &point) const +template +QPair::Node *, QRBTree::Node *> QTriangulator::ComplexToSimple::bounds(const QPodPoint &point) const { QRBTree::Node *current = m_edgeList.root; QPair::Node *, QRBTree::Node *> result(0, 0); @@ -1830,7 +1856,8 @@ QPair::Node *, QRBTree::Node *> QTriangulator::ComplexToSimple return result; } -QPair::Node *, QRBTree::Node *> QTriangulator::ComplexToSimple::outerBounds(const QPodPoint &point) const +template +QPair::Node *, QRBTree::Node *> QTriangulator::ComplexToSimple::outerBounds(const QPodPoint &point) const { QRBTree::Node *current = m_edgeList.root; QPair::Node *, QRBTree::Node *> result(0, 0); @@ -1886,7 +1913,8 @@ QPair::Node *, QRBTree::Node *> QTriangulator::ComplexToSimple return result; } -void QTriangulator::ComplexToSimple::splitEdgeListRange(QRBTree::Node *leftmost, QRBTree::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint) +template +void QTriangulator::ComplexToSimple::splitEdgeListRange(QRBTree::Node *leftmost, QRBTree::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint) { Q_ASSERT(leftmost && rightmost); @@ -1904,8 +1932,8 @@ void QTriangulator::ComplexToSimple::splitEdgeListRange(QRBTree::Node *left } } - -void QTriangulator::ComplexToSimple::reorderEdgeListRange(QRBTree::Node *leftmost, QRBTree::Node *rightmost) +template +void QTriangulator::ComplexToSimple::reorderEdgeListRange(QRBTree::Node *leftmost, QRBTree::Node *rightmost) { Q_ASSERT(leftmost && rightmost); @@ -1932,7 +1960,8 @@ void QTriangulator::ComplexToSimple::reorderEdgeListRange(QRBTree::Node *le calculateIntersection(storeRightmost->data, rightmost->data); } -void QTriangulator::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint) +template +void QTriangulator::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 +void QTriangulator::ComplexToSimple::fillPriorityQueue() { m_events.reset(); m_events.reserve(m_edges.size() * 2); @@ -1995,7 +2025,7 @@ void QTriangulator::ComplexToSimple::fillPriorityQueue() Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1); Q_ASSERT(m_edges.at(i).node == 0); Q_ASSERT(m_edges.at(i).pointingUp == m_edges.at(i).originallyPointingUp); - Q_ASSERT(m_edges.at(i).pointingUp == (m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from))); + Q_ASSERT(m_edges.at(i).pointingUp == (m_parent->m_vertices.at(qint32)(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from))); // Ignore zero-length edges. if (m_parent->m_vertices.at(m_edges.at(i).to) != m_parent->m_vertices.at(m_edges.at(i).from)) { QPodPoint upper = m_parent->m_vertices.at(m_edges.at(i).upper()); @@ -2010,7 +2040,8 @@ void QTriangulator::ComplexToSimple::fillPriorityQueue() sort(m_events.data(), m_events.size()); } -void QTriangulator::ComplexToSimple::calculateIntersections() +template +void QTriangulator::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 +int QTriangulator::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 +bool QTriangulator::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 +void QTriangulator::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 +void QTriangulator::ComplexToSimple::removeUnwantedEdgesAndConnect() { Q_ASSERT(m_edgeList.root == 0); // Initialize priority queue. @@ -2179,7 +2214,7 @@ void QTriangulator::ComplexToSimple::removeUnwantedEdgesAndConnect() while (current != b.second) { Q_ASSERT(current); Q_ASSERT(m_edges.at(current->data).node == current); - Q_ASSERT(qIntersectionPoint(event.point).isOnLine(m_parent->m_vertices.at(m_edges.at(current->data).from), m_parent->m_vertices.at(m_edges.at(current->data).to))); + Q_ASSERT(qIntersectionPoint(event.point).isOnLine(m_parent->m_vertices.at(m_edges.at(current->data).from), m_parent->m_vertices.at(qint32)(m_edges.at(current->data).to))); Q_ASSERT(m_parent->m_vertices.at(m_edges.at(current->data).from) == event.point || m_parent->m_vertices.at(m_edges.at(current->data).to) == event.point); insertEdgeIntoVectorIfWanted(orderedEdges, current->data); current = m_edgeList.next(current); @@ -2290,7 +2325,8 @@ void QTriangulator::ComplexToSimple::removeUnwantedEdgesAndConnect() } // end while } -void QTriangulator::ComplexToSimple::removeUnusedPoints() { +template +void QTriangulator::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 +bool QTriangulator::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 +inline bool QTriangulator::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 +QTriangulator::ComplexToSimple::DebugDialog::DebugDialog(ComplexToSimple *parent, int currentVertex) : m_parent(parent), m_vertex(currentVertex) { QDataBuffer &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 +void QTriangulator::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 +void QTriangulator::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 +void QTriangulator::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 +void QTriangulator::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 +void QTriangulator::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 +void QTriangulator::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 +void QTriangulator::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 +void QTriangulator::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 +bool QTriangulator::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::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfEdge(int edgeIndex) const +template +QRBTree::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfEdge(int edgeIndex) const { QRBTree::Node *current = m_edgeList.root; QRBTree::Node *result = 0; @@ -2591,7 +2638,8 @@ QRBTree::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfEdge(int ed } // Returns the rightmost edge left of the given point. -QRBTree::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfPoint(int pointIndex) const +template +QRBTree::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfPoint(int pointIndex) const { QRBTree::Node *current = m_edgeList.root; QRBTree::Node *result = 0; @@ -2609,7 +2657,8 @@ QRBTree::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfPoint(int p return result; } -void QTriangulator::SimpleToMonotone::classifyVertex(int i) +template +void QTriangulator::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 +void QTriangulator::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 +bool QTriangulator::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 +bool QTriangulator::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 +int QTriangulator::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 +void QTriangulator::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 +void QTriangulator::SimpleToMonotone::monotoneDecomposition() { if (m_edges.isEmpty()) return; @@ -2729,8 +2784,8 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition() Q_ASSERT(i < m_edges.size()); int j = m_edges.at(i).previous; Q_ASSERT(j < m_edges.size()); - m_clockwiseOrder = qPointIsLeftOfLine(m_parent->m_vertices.at(m_edges.at(i).from), - m_parent->m_vertices.at(m_edges.at(j).from), m_parent->m_vertices.at(m_edges.at(i).to)); + m_clockwiseOrder = qPointIsLeftOfLine(m_parent->m_vertices.at((quint32)m_edges.at(i).from), + m_parent->m_vertices.at((quint32)m_edges.at(j).from), m_parent->m_vertices.at((quint32)m_edges.at(i).to)); classifyVertices(); fillPriorityQueue(); @@ -2848,7 +2903,8 @@ void QTriangulator::SimpleToMonotone::monotoneDecomposition() createDiagonal(diagonals.at(i).first, diagonals.at(i).second); } -bool QTriangulator::SimpleToMonotone::CompareVertices::operator () (int i, int j) const +template +bool QTriangulator::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 +void QTriangulator::MonotoneToTriangles::decompose() { - QVector result; + QVector result; QDataBuffer 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 triangulator; + triangulator.initialize(polygon, count, hint, matrix); + QVertexSet vertexSet = triangulator.triangulate(); + triangleSet.vertices = vertexSet.vertices; + triangleSet.indices.setDataUint(vertexSet.indices); + + } else { + QTriangulator triangulator; + triangulator.initialize(polygon, count, hint, matrix); + QVertexSet 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 triangulator; + triangulator.initialize(path, matrix, lod); + QVertexSet vertexSet = triangulator.triangulate(); + triangleSet.vertices = vertexSet.vertices; + triangleSet.indices.setDataUint(vertexSet.indices); + } else { + QTriangulator triangulator; + triangulator.initialize(path, matrix, lod); + QVertexSet 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 triangulator; + triangulator.initialize(path, matrix, lod); + QVertexSet vertexSet = triangulator.triangulate(); + triangleSet.vertices = vertexSet.vertices; + triangleSet.indices.setDataUint(vertexSet.indices); + } else { + QTriangulator triangulator; + triangulator.initialize(path, matrix, lod); + QVertexSet 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 triangulator; + triangulator.initialize(path, matrix, lod); + QVertexSet vertexSet = triangulator.polyline(); + polyLineSet.vertices = vertexSet.vertices; + polyLineSet.indices.setDataUint(vertexSet.indices); + } else { + QTriangulator triangulator; + triangulator.initialize(path, matrix, lod); + QVertexSet 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 triangulator; + triangulator.initialize(path, matrix, lod); + QVertexSet vertexSet = triangulator.polyline(); + polyLineSet.vertices = vertexSet.vertices; + polyLineSet.indices.setDataUint(vertexSet.indices); + } else { + QTriangulator triangulator; + triangulator.initialize(path, matrix, lod); + QVertexSet 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 &data) + { + t = UnsignedInt; + indices32 = data; + } + + inline void setDataUshort(const QVector &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 indices32; + QVector 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 vertices; // [x[0], y[0], x[1], y[1], x[2], ...] - QVector 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 vertices; // [x[0], y[0], x[1], y[1], x[2], ...] - QVector indices; - + QVertexIndexVector indices; }; // The vertex coordinates of the returned triangle set will be rounded to a grid with a mesh size diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 6259cca..e81e849 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -346,6 +346,17 @@ struct QGLExtensionFuncs qt_glEGLImageTargetTexture2DOES = 0; qt_glEGLImageTargetRenderbufferStorageOES = 0; #endif + + // OES_element_index_uint +#if !defined(QT_OPENGL_ES) + qt_glSupportsElementIndexUint = true; +#else + QString extensions = reinterpret_cast(glGetString(GL_EXTENSIONS)); + if (extensions.contains("GL_OES_element_index_uint")) + qt_glSupportsElementIndexUint = true; + else + qt_glSupportsElementIndexUint = false; +#endif } @@ -473,6 +484,7 @@ struct QGLExtensionFuncs _glEGLImageTargetRenderbufferStorageOES qt_glEGLImageTargetRenderbufferStorageOES; #endif + bool qt_glSupportsElementIndexUint; }; @@ -871,6 +883,8 @@ struct QGLExtensionFuncs #define glEGLImageTargetRenderbufferStorageOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetRenderbufferStorageOES #endif +#define glSupportsElementIndexUint QGLContextPrivate::extensionFuncs(ctx).qt_glSupportsElementIndexUint + extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx); bool qt_resolve_buffer_extensions(QGLContext *ctx); -- cgit v0.12 From 77a92b39b30bf14f6509dfb578bad8511ef9a32e Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 4 Oct 2010 09:34:07 +0200 Subject: Made javascriptcore depend on corelib. It lists "QT = core" in its profile, and may fail parallel builds if the dependency is not in place. RevBy: Benjamin Poulain --- src/src.pro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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):{ -- cgit v0.12 From 4207bded6577f24fb4c20cc84880fd48eb9c0c9b Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 4 Oct 2010 10:46:14 +0200 Subject: Fixed library ordering when linking to qtmain. Done-with: Liang Qi Reviewed-by: Trust me --- mkspecs/features/symbian/symbian_building.prf | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/symbian/symbian_building.prf b/mkspecs/features/symbian/symbian_building.prf index 539609d..614fb65 100644 --- a/mkspecs/features/symbian/symbian_building.prf +++ b/mkspecs/features/symbian/symbian_building.prf @@ -187,9 +187,11 @@ contains(TEMPLATE, app):!contains(QMAKE_LINK, "^@:.*") { linux-armcc: { QMAKE_LIBS += usrt2_2.lib dfpaeabi.dso dfprvct2_2.dso drtaeabi.dso scppnwdl.dso drtrvct2_2.dso h_t__uf.l\\(switch8.o\\) QMAKE_LIBS += -leexe.lib\\(uc_exe_.o\\) - contains(CONFIG, "qt"):contains(QT, "core") { #if linking with QtCore + contains(CONFIG, "qt"):contains(QT, "gui") { #if linking with QtCore + QMAKE_LIBS -= -lqtmain$${QT_LIBINFIX}.lib QMAKE_LIBS += -lqtmain$${QT_LIBINFIX}.lib } else { + QMAKE_LIBS -= -llibcrt0.lib QMAKE_LIBS += -llibcrt0.lib } } else :linux-gcce { @@ -197,9 +199,12 @@ contains(TEMPLATE, app):!contains(QMAKE_LINK, "^@:.*") { QMAKE_LIBS += \ -l:eexe.lib \ -l:usrt2_2.lib - contains(CONFIG, "qt"):contains(QT, "core") { #if linking with QtCore + contains(CONFIG, "qt"):contains(QT, "gui") { #if linking with QtCore + QMAKE_LIBS -= -l:qtmain$${QT_LIBINFIX}.lib QMAKE_LIBS += -l:qtmain$${QT_LIBINFIX}.lib } else { + QMAKE_LIBS -= -l:libcrt0.lib + QMAKE_LIBS -= -l:libcrt0_gcce.lib QMAKE_LIBS += -l:libcrt0_gcce.lib } QMAKE_LIBS += \ -- cgit v0.12