ubuntu-touch-coreapps-reviewers team mailing list archive
-
ubuntu-touch-coreapps-reviewers team
-
Mailing list archive
-
Message #04725
[Merge] lp:~mrqtros/ubuntu-docviewer-app/docviewer-sg-rendering into lp:ubuntu-docviewer-app/reboot
Roman Shchekin has proposed merging lp:~mrqtros/ubuntu-docviewer-app/docviewer-sg-rendering into lp:ubuntu-docviewer-app/reboot.
Commit message:
Multithreaded rendering.
Requested reviews:
Ubuntu Document Viewer Developers (ubuntu-docviewer-dev)
For more details, see:
https://code.launchpad.net/~mrqtros/ubuntu-docviewer-app/docviewer-sg-rendering/+merge/270157
SceneGraph rendering (via QQuickItem and QSGSimpleTextureNode) instead of direct painting (via QQuickPaintedItem).
--
Your team Ubuntu Document Viewer Developers is requested to review the proposed merge of lp:~mrqtros/ubuntu-docviewer-app/docviewer-sg-rendering into lp:ubuntu-docviewer-app/reboot.
=== modified file 'po/com.ubuntu.docviewer.pot'
--- po/com.ubuntu.docviewer.pot 2015-08-04 16:01:37 +0000
+++ po/com.ubuntu.docviewer.pot 2015-09-04 10:33:13 +0000
@@ -8,7 +8,7 @@
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-12 21:23+0200\n"
+"POT-Creation-Date: 2015-09-02 14:29+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -33,7 +33,7 @@
msgstr ""
#: ../src/app/docviewer-application.cpp:171
-#: /home/stefano/Progetti/docviewer/Libreoffice/build-lo-tiled-rendering-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:1
+#: /home/qtros/dev/build-DocViewer-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:1
msgid "Document Viewer"
msgstr ""
@@ -149,32 +149,33 @@
msgid "%1 byte"
msgstr ""
-#: ../src/app/qml/documentPage/DeleteFileDialog.qml:28
+#: ../src/app/qml/documentPage/DeleteFileDialog.qml:36
msgid "Delete file"
msgstr ""
-#: ../src/app/qml/documentPage/DeleteFileDialog.qml:29
+#: ../src/app/qml/documentPage/DeleteFileDialog.qml:37
#, qt-format
msgid "Delete %1 file"
msgid_plural "Delete %1 files"
msgstr[0] ""
msgstr[1] ""
-#: ../src/app/qml/documentPage/DeleteFileDialog.qml:30
-#: ../src/app/qml/documentPage/DeleteFileDialog.qml:31
+#: ../src/app/qml/documentPage/DeleteFileDialog.qml:38
+#: ../src/app/qml/documentPage/DeleteFileDialog.qml:39
msgid "Are you sure you want to permanently delete this file?"
msgid_plural "Are you sure you want to permanently delete these files?"
msgstr[0] ""
msgstr[1] ""
-#: ../src/app/qml/documentPage/DeleteFileDialog.qml:36
+#: ../src/app/qml/documentPage/DeleteFileDialog.qml:44
#: ../src/app/qml/documentPage/DocumentPagePickModeHeader.qml:27
#: ../src/app/qml/loView/LOViewGotoDialog.qml:52
#: ../src/app/qml/pdfView/PdfViewGotoDialog.qml:52
msgid "Cancel"
msgstr ""
-#: ../src/app/qml/documentPage/DeleteFileDialog.qml:41
+#: ../src/app/qml/documentPage/DeleteFileDialog.qml:49
+#: ../src/app/qml/documentPage/DocumentDelegateActions.qml:25
#: ../src/app/qml/documentPage/DocumentPageSelectionModeHeader.qml:82
msgid "Delete"
msgstr ""
@@ -191,47 +192,35 @@
#. TRANSLATORS: %1 refers to a time formatted as Locale.ShortFormat (e.g. hh:mm). It depends on system settings.
#. http://qt-project.org/doc/qt-4.8/qlocale.html#FormatType-enum
-#: ../src/app/qml/documentPage/DocumentGridDelegate.qml:35
+#: ../src/app/qml/documentPage/DocumentGridDelegate.qml:32
+#: ../src/app/qml/documentPage/DocumentListDelegate.qml:37
#, qt-format
msgid "Today, %1"
msgstr ""
#. TRANSLATORS: %1 refers to a time formatted as Locale.ShortFormat (e.g. hh:mm). It depends on system settings.
#. http://qt-project.org/doc/qt-4.8/qlocale.html#FormatType-enum
-#: ../src/app/qml/documentPage/DocumentGridDelegate.qml:40
+#: ../src/app/qml/documentPage/DocumentGridDelegate.qml:37
+#: ../src/app/qml/documentPage/DocumentListDelegate.qml:42
#, qt-format
msgid "Yesterday, %1"
msgstr ""
#. TRANSLATORS: this is a datetime formatting string,
#. see http://qt-project.org/doc/qt-5/qml-qtqml-date.html#details for valid expressions.
-#: ../src/app/qml/documentPage/DocumentGridDelegate.qml:45
+#: ../src/app/qml/documentPage/DocumentGridDelegate.qml:42
#: ../src/app/qml/documentPage/DocumentListDelegate.qml:58
msgid "dddd, hh:mm"
msgstr ""
#. TRANSLATORS: this is a datetime formatting string,
#. see http://qt-project.org/doc/qt-5/qml-qtqml-date.html#details for valid expressions.
-#: ../src/app/qml/documentPage/DocumentGridDelegate.qml:49
+#: ../src/app/qml/documentPage/DocumentGridDelegate.qml:46
#: ../src/app/qml/documentPage/DocumentListDelegate.qml:47
#: ../src/app/qml/documentPage/DocumentListDelegate.qml:63
msgid "dd-MM-yyyy hh:mm"
msgstr ""
-#. TRANSLATORS: this is a datetime formatting string, and the
-#. singlequote is an escape character.
-#. See http://qt-project.org/doc/qt-5/qml-qtqml-date.html#details for valid expressions.
-#: ../src/app/qml/documentPage/DocumentListDelegate.qml:36
-msgid "'Today', hh:mm"
-msgstr ""
-
-#. TRANSLATORS: this is a datetime formatting string, and the
-#. singlequote is an escape character.
-#. See http://qt-project.org/doc/qt-5/qml-qtqml-date.html#details for valid expressions.
-#: ../src/app/qml/documentPage/DocumentListDelegate.qml:42
-msgid "'Yesterday', hh:mm"
-msgstr ""
-
#: ../src/app/qml/documentPage/DocumentListView.qml:157
msgid "Today"
msgstr ""
@@ -414,6 +403,6 @@
msgid "Open"
msgstr ""
-#: /home/stefano/Progetti/docviewer/Libreoffice/build-lo-tiled-rendering-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:2
+#: /home/qtros/dev/build-DocViewer-Desktop-Default/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-04-29 16:06:32 +0000
+++ src/app/CMakeLists.txt 2015-09-04 10:33:13 +0000
@@ -19,7 +19,7 @@
add_executable(ubuntu-docviewer-app ${docviewer_SRCS})
-qt5_use_modules(ubuntu-docviewer-app Widgets Gui Qml Quick DBus)
+qt5_use_modules(ubuntu-docviewer-app Widgets Gui Qml Quick DBus Concurrent)
target_link_libraries( ubuntu-docviewer-app
${CONTENTHUB_LIBRARIES}
=== modified file 'src/app/command-line-parser.cpp'
--- src/app/command-line-parser.cpp 2015-04-29 15:23:32 +0000
+++ src/app/command-line-parser.cpp 2015-09-04 10:33:13 +0000
@@ -30,8 +30,8 @@
CommandLineParser::CommandLineParser()
: m_pickMode(false),
+ m_isFullscreen(false),
m_testability(false),
- m_isFullscreen(false),
m_documentFile(""),
m_documentsDir("")
{
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt'
--- src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2015-08-25 22:35:28 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2015-09-04 10:33:13 +0000
@@ -13,6 +13,7 @@
lodocument.cpp
loview.cpp
tileitem.cpp
+ sgtileitem.cpp
${QML_SRCS}
)
@@ -20,6 +21,7 @@
set(libreofficetoolkitqmlplugin_HDRS
twips.h
config.h
+ sgtileitem.h
)
add_library(libreofficetoolkitqmlplugin MODULE
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/LOViewer.qml'
--- src/plugin/libreofficetoolkit-qml-plugin/LOViewer.qml 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/LOViewer.qml 2015-09-04 10:33:13 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import DocumentViewer.LibreOffice 1.0 as LibreOffice
+
+Flickable {
+ id: rootFlickable
+
+ property alias document: view.document
+ property alias zoomFactor: view.zoomFactor
+ property alias cacheBuffer: view.cacheBuffer
+
+ contentHeight: view.height * view.zoomFactor
+ contentWidth: view.width * view.zoomFactor
+
+ boundsBehavior: Flickable.StopAtBounds
+
+ LibreOffice.View {
+ id: view
+
+ parentFlickable: rootFlickable
+ }
+}
=== removed file 'src/plugin/libreofficetoolkit-qml-plugin/LOViewer.qml'
--- src/plugin/libreofficetoolkit-qml-plugin/LOViewer.qml 2015-07-26 17:33:51 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/LOViewer.qml 1970-01-01 00:00:00 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 Canonical, Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 3.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import QtQuick 2.4
-import DocumentViewer.LibreOffice 1.0 as LibreOffice
-
-Flickable {
- id: rootFlickable
-
- property alias document: view.document
- property alias zoomFactor: view.zoomFactor
- property alias cacheBuffer: view.cacheBuffer
-
- contentHeight: view.height * view.zoomFactor
- contentWidth: view.width * view.zoomFactor
-
- boundsBehavior: Flickable.StopAtBounds
-
- LibreOffice.View {
- id: view
-
- parentFlickable: rootFlickable
- }
-}
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2015-07-23 01:05:20 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2015-09-04 10:33:13 +0000
@@ -28,6 +28,10 @@
// TODO: Error management
+#ifdef DEBUG_TILE_BENCHMARK
+#include <QElapsedTimer>
+#endif
+
lok::Office *LODocument::s_office = nullptr;
LODocument::LODocument()
@@ -105,6 +109,12 @@
QImage LODocument::paintTile(QSize canvasSize, QRect tileSize)
{
QImage result = QImage(canvasSize.width(), canvasSize.height(), QImage::Format_RGB32);
+
+#ifdef DEBUG_TILE_BENCHMARK
+ QElapsedTimer renderTimer;
+ renderTimer.start();
+#endif
+
m_document->paintTile(result.bits(),
canvasSize.width(), canvasSize.height(),
Twips::convertPixelsToTwips(tileSize.x()),
@@ -112,6 +122,10 @@
Twips::convertPixelsToTwips(tileSize.width()),
Twips::convertPixelsToTwips(tileSize.height()));
+#ifdef DEBUG_TILE_BENCHMARK
+ qDebug() << "Time to render the tile:" << renderTimer.elapsed() << "ms";
+#endif
+
return result.rgbSwapped();
}
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2015-07-26 17:33:51 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2015-09-04 10:33:13 +0000
@@ -17,6 +17,7 @@
#include "loview.h"
#include "lodocument.h"
#include "tileitem.h"
+#include "sgtileitem.h"
#include "twips.h"
#include "config.h"
@@ -29,7 +30,7 @@
// updatePaintNode(QSGNode * oldNode, UpdatePaintNodeData * data)
LOView::LOView(QQuickItem *parent)
- : QQuickPaintedItem(parent)
+ : QQuickItem(parent) //QQuickPaintedItem(parent)
, m_parentFlickable(nullptr)
, m_document(nullptr)
, m_zoomFactor(1.0)
@@ -46,17 +47,17 @@
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateVisibleRect()));
}
-void LOView::paint(QPainter *painter)
-{
- Q_FOREACH(TileItem* tile, m_tiles) {
- painter->drawImage(tile->area(), tile->texture());
- tile->setPainted(true);
+//void LOView::paint(QPainter *painter)
+//{
+// Q_FOREACH(TileItem* tile, m_tiles) {
+// painter->drawImage(tile->area(), tile->texture());
+// tile->setPainted(true);
-#ifdef DEBUG_SHOW_TILE_BORDER
- painter->drawRect(tile->area());
-#endif
- }
-}
+//#ifdef DEBUG_SHOW_TILE_BORDER
+// painter->drawRect(tile->area());
+//#endif
+// }
+//}
// Returns the parent QML Flickable
QQuickItem* LOView::parentFlickable() const
@@ -170,18 +171,21 @@
if (!m_tiles.isEmpty()) {
auto i = m_tiles.begin();
while (i != m_tiles.end()) {
- TileItem* tile = i.value();
-
- if (!m_bufferArea.intersects(tile->area())) {
- tile->releaseTexture();
- i = m_tiles.erase(i);
-
-#ifdef DEBUG_VERBOSE
- qDebug() << "Removing tile indexed as" << i.key();
-#endif
- } else {
- ++i;
+ SGTileItem* sgtile = i.value();
+
+ // Ok - we still need this item.
+ if (m_bufferArea.intersects(sgtile->area())) {
+ i++;
+ continue;
}
+
+ // Out of buffer - we should delete this item.
+#ifdef DEBUG_VERBOSE
+ qDebug() << "Removing tile indexed as" << i.key();
+#endif
+
+ sgtile->dispose();
+ i = m_tiles.erase(i);
}
}
@@ -223,9 +227,9 @@
qDebug() << "Creating tile indexed as" << index;
#endif
- auto tile = new TileItem(rect, m_document);
- connect(tile, SIGNAL(textureChanged()), this, SLOT(update()));
- tile->requestTexture();
+ auto tile = new SGTileItem(rect, m_document, this);
+ // TODO When we should update with SG?
+ // connect(tile, SIGNAL(textureChanged()), this, SLOT(update()));
// Append the tile in the map
m_tiles.insert(index, tile);
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.h'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.h 2015-07-26 17:33:51 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.h 2015-09-04 10:33:13 +0000
@@ -18,12 +18,14 @@
#define LOVIEW_H
#include <QQuickPaintedItem>
+#include <QQuickItem>
#include <QTimer>
class LODocument;
class TileItem;
+class SGTileItem;
-class LOView : public QQuickPaintedItem
+class LOView : public QQuickItem // QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QQuickItem* parentFlickable READ parentFlickable WRITE setParentFlickable NOTIFY parentFlickableChanged)
@@ -37,7 +39,7 @@
LOView(QQuickItem *parent = 0);
~LOView();
- void paint(QPainter *painter);
+// void paint(QPainter *painter);
QQuickItem* parentFlickable() const;
void setParentFlickable(QQuickItem* flickable);
@@ -74,7 +76,7 @@
QTimer m_updateTimer;
- QMap<int, TileItem*> m_tiles;
+ QMap<int, SGTileItem*> m_tiles;
void generateTiles(int x1, int y1, int x2, int y2, int tilesPerWidth);
void createTile(int index, QRect rect);
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp 2015-09-04 10:33:13 +0000
@@ -0,0 +1,73 @@
+#include "sgtileitem.h"
+
+#include "lodocument.h"
+#include "config.h"
+
+SGTileItem::SGTileItem(const QRect &area, LODocument *document, QQuickItem *parent)
+ : QQuickItem(parent)
+ , m_area(area)
+ , m_document(document)
+ , m_state(SgstInitial)
+{
+ setFlag(ItemHasContents, true);
+}
+
+SGTileItem::~SGTileItem()
+{ }
+
+void SGTileItem::dispose()
+{
+ if (m_state.loadAcquire() != SgstRendering)
+ deleteLater();
+ m_state.storeRelease(SgstDisposed);
+ // qDebug() << "---- dispose called: " << this << m_state;
+}
+
+QSGNode *SGTileItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
+{
+ QSGSimpleTextureNode* node = static_cast<QSGSimpleTextureNode*>(oldNode);
+ QQuickWindow* wnd = window();
+
+ if (!node && wnd) {
+ if (this->m_state.loadAcquire() == SgstInitial) {
+ m_state.storeRelease(SgstRendering);
+ QtConcurrent::run( [=] {
+
+ QImage img;
+
+ // By this time already can be disposed, so it's better to ckeck again.
+ if (this->m_state.loadAcquire() == SgstRendering)
+ img = m_document->paintTile(this->area().size(), this->area());
+
+ if (this->m_state.loadAcquire() == SgstDisposed)
+ qDebug() << "Already disposed:" << m_state.loadAcquire();
+ QMetaObject::invokeMethod(this, "renderCallback", Q_ARG(QImage, img));
+
+ });
+ } else if (m_state.loadAcquire() == SgstActive) {
+ QImage image = m_data;
+ auto texture = wnd->createTextureFromImage(image);
+ node = new QSGSimpleTextureNode();
+ node->setTexture(texture);
+ node->setOwnsTexture(true);
+ node->setRect(m_area);
+ }
+ }
+
+ return node;
+}
+
+void SGTileItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ QQuickItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+void SGTileItem::renderCallback(QImage image)
+{
+ if (m_state.loadAcquire() == SgstRendering) {
+ m_data = image;
+ m_state.storeRelease(SgstActive);
+ update();
+ } else deleteLater();
+}
+
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h'
--- src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h 2015-09-04 10:33:13 +0000
@@ -0,0 +1,54 @@
+#ifndef SGTILEITEM_H
+#define SGTILEITEM_H
+
+#include <QQuickItem>
+#include <QQuickWindow>
+#include <QSGSimpleTextureNode>
+#include <QImage>
+#include <QtConcurrent/QtConcurrent>
+#include <QAtomicInteger>
+
+enum SGTileItemState
+{
+ SgstInitial = 1,
+ SgstRendering,
+ SgstActive,
+ SgstDisposed
+};
+
+class LODocument;
+
+class SGTileItem : public QQuickItem
+{
+ Q_OBJECT
+public:
+ SGTileItem(const QRect &area, LODocument *document, QQuickItem *parent = 0);
+ ~SGTileItem();
+
+ inline QRect area() const { return m_area; }
+ inline void setArea(const QRect &area) { m_area = area; }
+
+ inline LODocument* document() const { return m_document; }
+ inline void setDocument(LODocument* document) { m_document = document; }
+
+ void dispose();
+
+protected:
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+
+private:
+ Q_INVOKABLE void renderCallback(QImage image);
+
+signals:
+
+private:
+ QRect m_area;
+ LODocument* m_document;
+ QImage m_data;
+ QAtomicInteger<int> m_state;
+
+public slots:
+};
+
+#endif // SGTILEITEM_H
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/tileitem.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/tileitem.cpp 2015-07-22 16:44:39 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/tileitem.cpp 2015-09-04 10:33:13 +0000
@@ -160,12 +160,16 @@
// Render the texture for this tile.
void RenderTask::run()
{
+ // Can cause crash if document is nullptr.
+ if (!m_document)
+ return;
+
#ifdef DEBUG_TILE_BENCHMARK
QElapsedTimer renderTimer;
renderTimer.start();
#endif
- QImage render = this->document()->paintTile(this->area().size(),
+ QImage render = m_document->paintTile(this->area().size(),
this->area());
Q_EMIT renderCompleted(render);
Follow ups