# HG changeset patch # User Yuya Nishihara # Date 1583649877 -32400 # Sun Mar 08 15:44:37 2020 +0900 # Node ID 0c3fadd4c1abc38b6e594e1af16fe5f4a5c810f6 # Parent cac26c8a1feb88161a0c96fbf3d85cc4b1875737 try batch rendering of list items diff --git a/quickitemdelegate.cpp b/quickitemdelegate.cpp --- a/quickitemdelegate.cpp +++ b/quickitemdelegate.cpp @@ -13,13 +13,18 @@ #include #include "quickitemdelegate.h" +namespace { +constexpr int BATCH_SIZE = 10; +} + QuickItemDelegate::QuickItemDelegate(QObject *parent) : QStyledItemDelegate(parent), engine_(new QQmlEngine(this)), component_(new QQmlComponent(engine_, this)), //renderControl_(new QQuickRenderControl(this)), window_(std::make_unique(/*renderControl_*/)), - imageCache_() + image_(), + imageOffset_(0) { // XXX /* @@ -36,51 +41,58 @@ // XXX auto *context = engine_->rootContext(); - context->setContextProperty(QStringLiteral("itemIndex"), {}); - context->setContextProperty(QStringLiteral("itemText"), {}); + context->setContextProperty(QStringLiteral("model_"), nullptr); + context->setContextProperty(QStringLiteral("offset_"), imageOffset_); component_->setData(QByteArrayLiteral(R"( import QtQuick 2.12 - Row { + ListView { anchors.fill: parent - spacing: 4 - leftPadding: 4 - rightPadding: 4 + model: model_ + contentY: 28 * offset_ + delegate: Row { + anchors.left: parent.left + anchors.right: parent.right + height: 28 + spacing: 4 + leftPadding: 4 + rightPadding: 4 - Rectangle { - anchors.verticalCenter: parent.verticalCenter - width: indexText.width + 4 - height: indexText.height + 4 - color: "#ccc" - Text { - id: indexText - anchors.centerIn: parent - text: "#" + itemIndex - } - } - - Text { - anchors.verticalCenter: parent.verticalCenter - text: itemText - } - - Text { - anchors.verticalCenter: parent.verticalCenter - color: "gray" - Timer { - interval: 1000 - running: true - repeat: true - onTriggered: { - parent.text = Qt.formatDateTime(new Date(), "yyyy-MM-dd hh:mm:ss"); + Rectangle { + anchors.verticalCenter: parent.verticalCenter + width: indexText.width + 4 + height: indexText.height + 4 + color: "#ccc" + Text { + id: indexText + anchors.centerIn: parent + text: "#" + model.index } } - } + + Text { + anchors.verticalCenter: parent.verticalCenter + // TODO: text: model.modelData + } - Image { - anchors.verticalCenter: parent.verticalCenter - source: "file:/usr/share/icons/Tango/16x16/emotes/face-crying.png" + Text { + anchors.verticalCenter: parent.verticalCenter + color: "gray" + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: { + parent.text = Qt.formatDateTime(new Date(), "yyyy-MM-dd hh:mm:ss"); + } + } + } + + Image { + anchors.verticalCenter: parent.verticalCenter + source: "file:/usr/share/icons/Tango/16x16/emotes/face-crying.png" + } } } )"), QUrl()); // TODO @@ -90,7 +102,7 @@ Q_ASSERT(item); item->setParentItem(window_->contentItem()); window_->create(); - window_->resize(100, 28); + window_->resize(100, 28 * BATCH_SIZE); } QuickItemDelegate::~QuickItemDelegate() = default; @@ -98,22 +110,19 @@ void QuickItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - QImage image; - if (index.row() < imageCache_.size()) { - // TODO: invalidate cache if model data changed - image = imageCache_.at(index.row()); - } - - if (image.isNull() || image.width() < option.rect.width()) { - window_->resize(option.rect.size()); + // TODO: invalidate cache if model data changed + // TODO: better batch offset selection + if (image_.isNull() || index.row() < imageOffset_ || index.row() >= imageOffset_ + BATCH_SIZE) { + // TODO: batch size + window_->resize(option.rect.width(), 28 * BATCH_SIZE); + imageOffset_ = index.row() / BATCH_SIZE * BATCH_SIZE; auto *context = engine_->rootContext(); - context->setContextProperty(QStringLiteral("itemIndex"), index.row()); - context->setContextProperty(QStringLiteral("itemText"), index.data()); - image = window_->grabWindow(); - if (imageCache_.size() <= index.row()) { - imageCache_.resize(index.row() + 1); - } - imageCache_[index.row()] = image; + context->setContextProperty( + QStringLiteral("model_"), + const_cast(static_cast(index.model()))); + context->setContextProperty(QStringLiteral("offset_"), imageOffset_); + // TODO: synchronized? + image_ = window_->grabWindow(); } /* @@ -123,8 +132,8 @@ */ painter->save(); painter->setClipRect(option.rect); - // TODO: synchronized? - painter->drawImage(option.rect.left(), option.rect.top(), image); + painter->drawImage(option.rect.left(), option.rect.top(), image_, + 0, 28 * (index.row() - imageOffset_), image_.width(), 28); //painter->drawImage(0, 0, renderControl_->grab()); painter->restore(); } @@ -133,5 +142,5 @@ const QModelIndex &/*index*/) const { // TODO - return window_->size(); + return {100, 28}; } diff --git a/quickitemdelegate.h b/quickitemdelegate.h --- a/quickitemdelegate.h +++ b/quickitemdelegate.h @@ -27,7 +27,8 @@ QQmlComponent *component_; QQuickRenderControl *renderControl_; std::unique_ptr window_; - mutable QVector imageCache_; // TODO: LRU + mutable QImage image_; // TODO: LRU + mutable int imageOffset_; }; #endif // QUICKITEMDELEGATE_H