Roman Shchekin has proposed merging lp:~mrqtros/ubuntu-docviewer-app/ubuntu-docviewer-app-renderengine-move into lp:ubuntu-docviewer-app.
Commit message: RenderEngine now become application-wide tool Requested reviews: Ubuntu Document Viewer Developers (ubuntu-docviewer-dev) For more details, see: https://code.launchpad.net/~mrqtros/ubuntu-docviewer-app/ubuntu-docviewer-app-renderengine-move/+merge/281328 RenderEngine now become application-wide tool. This refactoring is required for easy transition to asynchonious PDF rendering. -- Your team Ubuntu Document Viewer Developers is requested to review the proposed merge of lp:~mrqtros/ubuntu-docviewer-app/ubuntu-docviewer-app-renderengine-move into lp:ubuntu-docviewer-app.
=== modified file 'po/com.ubuntu.docviewer.pot' --- po/com.ubuntu.docviewer.pot 2015-12-02 15:12:15 +0000 +++ po/com.ubuntu.docviewer.pot 2015-12-23 21:30:11 +0000 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-12-02 16:11+0100\n" +"POT-Creation-Date: 2015-12-12 13:04+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <l...@li.org>\n" @@ -211,7 +211,7 @@ msgstr "" #: ../src/app/qml/documentPage/DocumentPage.qml:23 -#: /tmp/build-ubuntu-docviewer-app-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:3 +#: /home/qtros/dev/ubuntu-docviewer-app-uitk-13-ethalone-build/po/com.ubuntu.docviewer.desktop.in.in.h:3 msgid "Documents" msgstr "" @@ -435,10 +435,10 @@ msgid "copy %1" msgstr "" -#: /tmp/build-ubuntu-docviewer-app-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:1 +#: /home/qtros/dev/ubuntu-docviewer-app-uitk-13-ethalone-build/po/com.ubuntu.docviewer.desktop.in.in.h:1 msgid "Document Viewer" msgstr "" -#: /tmp/build-ubuntu-docviewer-app-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:2 +#: /home/qtros/dev/ubuntu-docviewer-app-uitk-13-ethalone-build/po/com.ubuntu.docviewer.desktop.in.in.h:2 msgid "documents;viewer;pdf;reader;" msgstr "" === modified file 'src/app/CMakeLists.txt' --- src/app/CMakeLists.txt 2015-11-30 12:12:10 +0000 +++ src/app/CMakeLists.txt 2015-12-23 21:30:11 +0000 @@ -22,6 +22,8 @@ set(docviewer_SRCS main.cpp + renderengine.cpp + rendertask.cpp ${QML_SRCS} ) === added file 'src/app/renderengine.cpp' --- src/app/renderengine.cpp 1970-01-01 00:00:00 +0000 +++ src/app/renderengine.cpp 2015-12-23 21:30:11 +0000 @@ -0,0 +1,92 @@ +#include "renderengine.h" +#include <QtConcurrent/QtConcurrent> +#include <QThread> + +RenderEngine* RenderEngine::s_instance = nullptr; + +RenderEngine::RenderEngine(): + QObject(nullptr) + ,m_activeTaskCount(0) + ,m_lastTask(nullptr) +{ + int itc = QThread::idealThreadCount(); + m_idealThreadCount = itc == -1 ? DefaultIdealThreadCount : itc; + + // For QMetaObject::invoke. + qRegisterMetaType<AbstractRenderTask*>(); +} + +void RenderEngine::enqueueTask(AbstractRenderTask *task) +{ + m_queue.enqueue(task); + doNextTask(); +} + +void RenderEngine::dequeueTask(int id) +{ + for (int i = 0; i < m_queue.size(); i++) { + auto task = m_queue.at(i); + if (task->id() == id) { + m_queue.removeAt(i); + disposeLater(task); + break; + } + } +} + +void RenderEngine::internalRenderCallback(AbstractRenderTask* task, QImage img) +{ + m_activeTaskCount--; + + if (!m_activeTaskCount) { + m_lastTask = nullptr; + doDispose(); + } + + // Notify about result. + emit taskRenderFinished(task, img); + + doNextTask(); + disposeLater(task); +} + +void RenderEngine::disposeLater(AbstractRenderTask *task) +{ + m_disposedTasks.append(task); +} + +void RenderEngine::doDispose() +{ + for (int i = 0; i < m_disposedTasks.size(); ++i) + delete m_disposedTasks.at(i); + m_disposedTasks.clear(); +} + +void RenderEngine::doNextTask() +{ +#ifdef DEBUG_VERBOSE + qDebug() << " ---- doNextTask" << m_activeTaskCount << m_queue.count(); +#endif + + // Check for too much threads or empty queue. + if (m_activeTaskCount >= m_idealThreadCount || !m_queue.count()) + return; + + AbstractRenderTask* task = m_queue.head(); + + // If some tasks already in progress, we should ask task about + // compatibility of parallel execution with last the task. + if (m_activeTaskCount && !task->canBeRunInParallel(m_lastTask)) + return; + + task->prepare(); + + m_activeTaskCount++; + m_lastTask = m_queue.dequeue(); + + QtConcurrent::run( [=] { + QImage img = task->doWork(); + QMetaObject::invokeMethod(this, "internalRenderCallback", + Q_ARG(AbstractRenderTask*, task), Q_ARG(QImage, img)); + }); +} === added file 'src/app/renderengine.h' --- src/app/renderengine.h 1970-01-01 00:00:00 +0000 +++ src/app/renderengine.h 2015-12-23 21:30:11 +0000 @@ -0,0 +1,58 @@ +#ifndef RENDERENGINE_H +#define RENDERENGINE_H + +#include <QObject> +#include <QImage> +#include <QSharedPointer> +#include <QHash> +#include <QQueue> +#include <QAtomicInt> +#include <QList> + +//#include "lodocument.h" +#include "rendertask.h" + +class RenderEngine : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(RenderEngine) + + static RenderEngine* s_instance; + RenderEngine(); + + const int DefaultIdealThreadCount = 2; + +public: + void enqueueTask(AbstractRenderTask* task); // Takes ownership. + void dequeueTask(int id); + + static RenderEngine* instance() { + if(!s_instance) + s_instance = new RenderEngine(); + return s_instance; + } + + static int getNextId() { + static int idCounter = 0xDEAD0000; + return idCounter++; + } + +Q_SIGNALS: + void taskRenderFinished(AbstractRenderTask* task, QImage img); + +private: + Q_INVOKABLE void internalRenderCallback(AbstractRenderTask* task, QImage img); + void doNextTask(); + void disposeLater(AbstractRenderTask* task); // Delayed deletion, must be used in pair with "doDispose". + void doDispose(); // Deletes marked objects (disposeLater). + +private: + QQueue<AbstractRenderTask*> m_queue; + int m_activeTaskCount; + int m_idealThreadCount; + + AbstractRenderTask* m_lastTask; // WARNING: valid only when: m_activeTaskCount > 0. + QList<AbstractRenderTask*> m_disposedTasks; +}; + +#endif // RENDERENGINE_H === added file 'src/app/rendertask.cpp' --- src/app/rendertask.cpp 1970-01-01 00:00:00 +0000 +++ src/app/rendertask.cpp 2015-12-23 21:30:11 +0000 @@ -0,0 +1,1 @@ +#include "rendertask.h" === added file 'src/app/rendertask.h' --- src/app/rendertask.h 1970-01-01 00:00:00 +0000 +++ src/app/rendertask.h 2015-12-23 21:30:11 +0000 @@ -0,0 +1,38 @@ +#ifndef RENDERTASK_H +#define RENDERTASK_H + +#include <QObject> +#include <QImage> +#include <QSharedPointer> +#include <QHash> +#include <QQueue> + +/* Required for super-fast type detection. + * NOTE: only leaf nodes in inheritance tree have correct types. + */ +enum RenderTaskType +{ + RttUnknown = 0x0, + RttTile = 0x1, + RttImpressThumbnail = 0x2, + RttPdfPage = 0x3 +}; + +class AbstractRenderTask +{ +public: + virtual RenderTaskType type() { return RttUnknown; } + virtual QImage doWork() = 0 ; + virtual ~AbstractRenderTask() { } + virtual bool canBeRunInParallel(AbstractRenderTask*) { return true; } + virtual void prepare() = 0 ; + + int id() { return m_id; } + void setId(int i) { m_id = i; } +protected: + int m_id; +}; + +Q_DECLARE_METATYPE(AbstractRenderTask*) + +#endif // RENDERTASK_H === modified file 'src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt' --- src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2015-11-22 17:28:09 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2015-12-23 21:30:11 +0000 @@ -24,8 +24,7 @@ sgtileitem.cpp lopartsimageprovider.cpp lopartsmodel.cpp - renderengine.cpp - rendertask.cpp + lorendertask.cpp ${QML_SRCS} ) === modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp' --- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 2015-11-28 22:11:54 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 2015-12-23 21:30:11 +0000 @@ -16,7 +16,7 @@ #include "lopartsimageprovider.h" #include "lodocument.h" -#include "renderengine.h" +#include "../../app/renderengine.h" LOPartsImageProvider::LOPartsImageProvider(const QSharedPointer<LODocument>& d) : QQuickImageProvider(QQuickImageProvider::Image), === modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h' --- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 2015-11-28 22:11:54 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 2015-12-23 21:30:11 +0000 @@ -23,7 +23,7 @@ #include <QHash> #include <QDebug> -#include "rendertask.h" +#include "lorendertask.h" class LODocument; === modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h' --- src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 2015-11-28 19:19:26 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 2015-12-23 21:30:11 +0000 @@ -22,7 +22,7 @@ #include <QHash> #include <QSharedPointer> -#include "renderengine.h" +#include "../../app/renderengine.h" class LODocument; === added file 'src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp' --- src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp 1970-01-01 00:00:00 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp 2015-12-23 21:30:11 +0000 @@ -0,0 +1,25 @@ +#include "lorendertask.h" + +bool LoRenderTask::canBeRunInParallel(AbstractRenderTask* prevTask) +{ + Q_ASSERT(prevTask != nullptr); + if (prevTask->type() == RttTile || prevTask->type() == RttImpressThumbnail) { + LoRenderTask* loTask = static_cast<LoRenderTask*>(prevTask); + + // Another document or the same part in the same document can be run parallel. + return (loTask->document() != m_document || + loTask->part() == m_part); + } + + return true; +} + +QImage TileRenderTask::doWork() +{ + return m_document->paintTile(m_area.size(), m_area, m_zoom); +} + +QImage ThumbnailRenderTask::doWork() +{ + return m_document->paintThumbnail(m_size); +} === added file 'src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h' --- src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h 1970-01-01 00:00:00 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h 2015-12-23 21:30:11 +0000 @@ -0,0 +1,57 @@ +#ifndef LORENDERTASK_H +#define LORENDERTASK_H + +#include <QObject> +#include <QImage> +#include <QSharedPointer> +#include <QHash> +#include <QQueue> +#include <QAtomicInt> + +#include "../../app/rendertask.h" +#include "lodocument.h" + + +class LoRenderTask : public AbstractRenderTask +{ +public: + virtual bool canBeRunInParallel(AbstractRenderTask* prevTask); + virtual void prepare() { m_document->setDocumentPart(m_part); } + + int part() { return m_part; } + void setPart(int p) { m_part = p; } + QSharedPointer<LODocument> document() { return m_document; } + void setDocument(QSharedPointer<LODocument> d) { m_document = d; } +protected: + int m_part; + QSharedPointer<LODocument> m_document; +}; + +class TileRenderTask : public LoRenderTask +{ +public: + virtual RenderTaskType type() { return RttTile; } + virtual QImage doWork(); + + QRect area() { return m_area; } + void setArea(const QRect& a) { m_area = a; } + qreal zoom() { return m_zoom; } + void setZoom(qreal z) { m_zoom = z; } +protected: + QRect m_area; + qreal m_zoom; +}; + +class ThumbnailRenderTask : public LoRenderTask +{ +public: + virtual RenderTaskType type() { return RttImpressThumbnail; } + virtual QImage doWork(); + + qreal size() { return m_size; } + void setSize(qreal s) { m_size = s; } +protected: + qreal m_size; +}; + +#endif // LORENDERTASK_H === modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.h' --- src/plugin/libreofficetoolkit-qml-plugin/loview.h 2015-11-28 22:11:54 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/loview.h 2015-12-23 21:30:11 +0000 @@ -24,8 +24,8 @@ #include <QQmlEngine> #include "loerror.h" -#include "rendertask.h" -#include "renderengine.h" +#include "lorendertask.h" +#include "../../app/renderengine.h" #include "lopartsmodel.h" #include "lopartsimageprovider.h" === removed file 'src/plugin/libreofficetoolkit-qml-plugin/renderengine.cpp' --- src/plugin/libreofficetoolkit-qml-plugin/renderengine.cpp 2015-11-28 22:11:54 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/renderengine.cpp 1970-01-01 00:00:00 +0000 @@ -1,92 +0,0 @@ -#include "renderengine.h" -#include <QtConcurrent/QtConcurrent> -#include <QThread> - -RenderEngine* RenderEngine::s_instance = nullptr; - -RenderEngine::RenderEngine(): - QObject(nullptr) - ,m_activeTaskCount(0) - ,m_lastTask(nullptr) -{ - int itc = QThread::idealThreadCount(); - m_idealThreadCount = itc == -1 ? DefaultIdealThreadCount : itc; - - // For QMetaObject::invoke. - qRegisterMetaType<AbstractRenderTask*>(); -} - -void RenderEngine::enqueueTask(AbstractRenderTask *task) -{ - m_queue.enqueue(task); - doNextTask(); -} - -void RenderEngine::dequeueTask(int id) -{ - for (int i = 0; i < m_queue.size(); i++) { - auto task = m_queue.at(i); - if (task->id() == id) { - m_queue.removeAt(i); - disposeLater(task); - break; - } - } -} - -void RenderEngine::internalRenderCallback(AbstractRenderTask* task, QImage img) -{ - m_activeTaskCount--; - - if (!m_activeTaskCount) { - m_lastTask = nullptr; - doDispose(); - } - - // Notify about result. - emit taskRenderFinished(task, img); - - doNextTask(); - disposeLater(task); -} - -void RenderEngine::disposeLater(AbstractRenderTask *task) -{ - m_disposedTasks.append(task); -} - -void RenderEngine::doDispose() -{ - for (int i = 0; i < m_disposedTasks.size(); ++i) - delete m_disposedTasks.at(i); - m_disposedTasks.clear(); -} - -void RenderEngine::doNextTask() -{ -#ifdef DEBUG_VERBOSE - qDebug() << " ---- doNextTask" << m_activeTaskCount << m_queue.count(); -#endif - - // Check for too much threads or empty queue. - if (m_activeTaskCount >= m_idealThreadCount || !m_queue.count()) - return; - - AbstractRenderTask* task = m_queue.head(); - - // If some tasks already in progress, we should ask task about - // compatibility of parallel execution with last the task. - if (m_activeTaskCount && !task->canBeRunInParallel(m_lastTask)) - return; - - task->prepare(); - - m_activeTaskCount++; - m_lastTask = m_queue.dequeue(); - - QtConcurrent::run( [=] { - QImage img = task->doWork(); - QMetaObject::invokeMethod(this, "internalRenderCallback", - Q_ARG(AbstractRenderTask*, task), Q_ARG(QImage, img)); - }); -} === removed file 'src/plugin/libreofficetoolkit-qml-plugin/renderengine.h' --- src/plugin/libreofficetoolkit-qml-plugin/renderengine.h 2015-11-28 22:11:54 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/renderengine.h 1970-01-01 00:00:00 +0000 @@ -1,58 +0,0 @@ -#ifndef RENDERENGINE_H -#define RENDERENGINE_H - -#include <QObject> -#include <QImage> -#include <QSharedPointer> -#include <QHash> -#include <QQueue> -#include <QAtomicInt> -#include <QList> - -#include "lodocument.h" -#include "rendertask.h" - -class RenderEngine : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(RenderEngine) - - static RenderEngine* s_instance; - RenderEngine(); - - const int DefaultIdealThreadCount = 2; - -public: - void enqueueTask(AbstractRenderTask* task); // Takes ownership. - void dequeueTask(int id); - - static RenderEngine* instance() { - if(!s_instance) - s_instance = new RenderEngine(); - return s_instance; - } - - static int getNextId() { - static int idCounter = 0xDEAD0000; - return idCounter++; - } - -Q_SIGNALS: - void taskRenderFinished(AbstractRenderTask* task, QImage img); - -private: - Q_INVOKABLE void internalRenderCallback(AbstractRenderTask* task, QImage img); - void doNextTask(); - void disposeLater(AbstractRenderTask* task); // Delayed deletion, must be used in pair with "doDispose". - void doDispose(); // Deletes marked objects (disposeLater). - -private: - QQueue<AbstractRenderTask*> m_queue; - int m_activeTaskCount; - int m_idealThreadCount; - - AbstractRenderTask* m_lastTask; // WARNING: valid only when: m_activeTaskCount > 0. - QList<AbstractRenderTask*> m_disposedTasks; -}; - -#endif // RENDERENGINE_H === removed file 'src/plugin/libreofficetoolkit-qml-plugin/rendertask.cpp' --- src/plugin/libreofficetoolkit-qml-plugin/rendertask.cpp 2015-11-28 21:13:54 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/rendertask.cpp 1970-01-01 00:00:00 +0000 @@ -1,25 +0,0 @@ -#include "rendertask.h" - -bool LoRenderTask::canBeRunInParallel(AbstractRenderTask* prevTask) -{ - Q_ASSERT(prevTask != nullptr); - if (prevTask->type() == RttTile || prevTask->type() == RttImpressThumbnail) { - LoRenderTask* loTask = static_cast<LoRenderTask*>(prevTask); - - // Another document or the same part in the same document can be run parallel. - return (loTask->document() != m_document || - loTask->part() == m_part); - } - - return true; -} - -QImage TileRenderTask::doWork() -{ - return m_document->paintTile(m_area.size(), m_area, m_zoom); -} - -QImage ThumbnailRenderTask::doWork() -{ - return m_document->paintThumbnail(m_size); -} === removed file 'src/plugin/libreofficetoolkit-qml-plugin/rendertask.h' --- src/plugin/libreofficetoolkit-qml-plugin/rendertask.h 2015-11-28 22:11:54 +0000 +++ src/plugin/libreofficetoolkit-qml-plugin/rendertask.h 1970-01-01 00:00:00 +0000 @@ -1,83 +0,0 @@ -#ifndef RENDERTASK_H -#define RENDERTASK_H - -#include <QObject> -#include <QImage> -#include <QSharedPointer> -#include <QHash> -#include <QQueue> -#include <QAtomicInt> - -#include "lodocument.h" - -/* Required for super-fast type detection. - * NOTE: only leaf nodes in inheritance tree have correct types. - */ -enum RenderTaskType -{ - RttUnknown = 0x0, - RttTile = 0x1, - RttImpressThumbnail = 0x2, - RttPdfPage = 0x3 -}; - -class AbstractRenderTask -{ -public: - virtual RenderTaskType type() { return RttUnknown; } - virtual QImage doWork() = 0 ; - virtual ~AbstractRenderTask() { } - virtual bool canBeRunInParallel(AbstractRenderTask*) { return true; } - virtual void prepare() = 0 ; - - int id() { return m_id; } - void setId(int i) { m_id = i; } -protected: - int m_id; -}; - -Q_DECLARE_METATYPE(AbstractRenderTask*) - -class LoRenderTask : public AbstractRenderTask -{ -public: - virtual bool canBeRunInParallel(AbstractRenderTask* prevTask); - virtual void prepare() { m_document->setDocumentPart(m_part); } - - int part() { return m_part; } - void setPart(int p) { m_part = p; } - QSharedPointer<LODocument> document() { return m_document; } - void setDocument(QSharedPointer<LODocument> d) { m_document = d; } -protected: - int m_part; - QSharedPointer<LODocument> m_document; -}; - -class TileRenderTask : public LoRenderTask -{ -public: - virtual RenderTaskType type() { return RttTile; } - virtual QImage doWork(); - - QRect area() { return m_area; } - void setArea(const QRect& a) { m_area = a; } - qreal zoom() { return m_zoom; } - void setZoom(qreal z) { m_zoom = z; } -protected: - QRect m_area; - qreal m_zoom; -}; - -class ThumbnailRenderTask : public LoRenderTask -{ -public: - virtual RenderTaskType type() { return RttImpressThumbnail; } - virtual QImage doWork(); - - qreal size() { return m_size; } - void setSize(qreal s) { m_size = s; } -protected: - qreal m_size; -}; - -#endif // RENDERTASK_H
-- Mailing list: https://launchpad.net/~ubuntu-touch-coreapps-reviewers Post to : ubuntu-touch-coreapps-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~ubuntu-touch-coreapps-reviewers More help : https://help.launchpad.net/ListHelp