[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-kimageshop
Subject: [krita] /: Fix "openGL lag at zoom 2000 + rotation"
From: Dmitry Kazakov <dimula73 () gmail ! com>
Date: 2016-03-25 12:09:44
Message-ID: E1ajQYi-0000De-KU () scm ! kde ! org
[Download RAW message or body]
Git commit 08fd3aa8e554557728f60f8571e51364070c09e8 by Dmitry Kazakov.
Committed on 25/03/2016 at 12:08.
Pushed by dkazakov into branch 'master'.
Fix "openGL lag at zoom 2000 + rotation"
The problem was not related to the openGL actualy. It was caused
by the implementation of QPainter::clipRegion() which generated
20k+ rectangles from a rotated rect when rotation angle was near to
a 0 or 90deg.
WARNING for the future:
Never use QPainter::clipRegion(). Use KisPaintingUtils::safeClipRegion()
instead. It workarounds the issue returning a bit bigger rect.
Fixes T1446
BUG:355104
CC:kimageshop@kde.org
M +3 -1 libs/flake/KoShapeContainer.cpp
M +3 -1 libs/flake/KoShapeManager.cpp
M +0 -3 libs/flake/tools/KoCreateShapeStrategy.cpp
M +0 -2 libs/flake/tools/KoShapeRubberSelectStrategy.cpp
M +1 -0 libs/global/CMakeLists.txt
A +51 -0 libs/global/kis_painting_tweaks.cpp [License: GPL (v2+)]
A +45 -0 libs/global/kis_painting_tweaks.h [License: GPL (v2+)]
M +4 -1 plugins/flake/textshape/TextShape.cpp
M +2 -1 plugins/flake/textshape/textlayout/KoTextLayoutArea_paint.cpp
M +3 -1 plugins/flake/vectorshape/VectorShape.cpp
http://commits.kde.org/krita/08fd3aa8e554557728f60f8571e51364070c09e8
diff --git a/libs/flake/KoShapeContainer.cpp b/libs/flake/KoShapeContainer.cpp
index 74cdb23..411098c 100644
--- a/libs/flake/KoShapeContainer.cpp
+++ b/libs/flake/KoShapeContainer.cpp
@@ -29,6 +29,8 @@
#include <QPainter>
#include <QPainterPath>
+#include "kis_painting_tweaks.h"
+
KoShapeContainerPrivate::KoShapeContainerPrivate(KoShapeContainer *q)
: KoShapePrivate(q),
model(0)
@@ -173,7 +175,7 @@ void KoShapeContainer::paint(QPainter &painter, const \
KoViewConverter &converter m.scale(zoomX, zoomY);
painter.setClipPath(m.map(outline()), Qt::IntersectClip);
- QRectF toPaintRect = \
converter.viewToDocument(painter.clipRegion().boundingRect()); + QRectF \
toPaintRect = converter.viewToDocument(KisPaintingTweaks::safeClipBoundingRect(painter));
toPaintRect = transform().mapRect(toPaintRect);
// We'll use this clipRect to see if our child shapes lie within it.
// Because shape->boundingRect() uses absoluteTransformation(0) we'll
diff --git a/libs/flake/KoShapeManager.cpp b/libs/flake/KoShapeManager.cpp
index f44d4be..6f861f1 100644
--- a/libs/flake/KoShapeManager.cpp
+++ b/libs/flake/KoShapeManager.cpp
@@ -48,6 +48,8 @@
#include <QTimer>
#include <FlakeDebug.h>
+#include "kis_painting_tweaks.h"
+
void KoShapeManager::Private::updateTree()
{
@@ -227,7 +229,7 @@ void KoShapeManager::paint(QPainter &painter, const \
KoViewConverter &converter,
QList<KoShape*> unsortedShapes;
if (painter.hasClipping()) {
- QRectF rect = converter.viewToDocument(painter.clipRegion().boundingRect());
+ QRectF rect = \
converter.viewToDocument(KisPaintingTweaks::safeClipBoundingRect(painter)); \
unsortedShapes = d->tree.intersects(rect); } else {
unsortedShapes = shapes();
diff --git a/libs/flake/tools/KoCreateShapeStrategy.cpp \
b/libs/flake/tools/KoCreateShapeStrategy.cpp index 7e6ef1a..054a56b 100644
--- a/libs/flake/tools/KoCreateShapeStrategy.cpp
+++ b/libs/flake/tools/KoCreateShapeStrategy.cpp
@@ -119,9 +119,6 @@ void KoCreateShapeStrategy::paint(QPainter &painter, const \
KoViewConverter &conv matrix.scale(xscale, yscale);
painter.translate(paintRect.left(), paintRect.top());
- if (painter.hasClipping())
- paintRect = paintRect.intersect(painter.clipRegion().boundingRect());
-
painter.setTransform(matrix, true);
painter.drawPath(m_outline);
painter.restore();
diff --git a/libs/flake/tools/KoShapeRubberSelectStrategy.cpp \
b/libs/flake/tools/KoShapeRubberSelectStrategy.cpp index 8240593..0b0a0e8 100644
--- a/libs/flake/tools/KoShapeRubberSelectStrategy.cpp
+++ b/libs/flake/tools/KoShapeRubberSelectStrategy.cpp
@@ -52,8 +52,6 @@ void KoShapeRubberSelectStrategy::paint(QPainter &painter, const \
KoViewConverter QRectF paintRect = converter.documentToView(d->selectedRect());
paintRect = paintRect.normalized();
paintRect.adjust(0., -0.5, 0.5, 0.);
- if (painter.hasClipping())
- paintRect = paintRect.intersect(painter.clipRegion().boundingRect());
painter.drawRect(paintRect);
}
diff --git a/libs/global/CMakeLists.txt b/libs/global/CMakeLists.txt
index efb0d98..42a33fe 100644
--- a/libs/global/CMakeLists.txt
+++ b/libs/global/CMakeLists.txt
@@ -12,6 +12,7 @@ set(kritaglobal_LIB_SRCS
kis_memory_leak_tracker.cpp
kis_shared.cpp
kis_dom_utils.cpp
+ kis_painting_tweaks.cpp
)
add_library(kritaglobal SHARED ${kritaglobal_LIB_SRCS} )
diff --git a/libs/global/kis_painting_tweaks.cpp \
b/libs/global/kis_painting_tweaks.cpp new file mode 100644
index 0000000..1c59e1a
--- /dev/null
+++ b/libs/global/kis_painting_tweaks.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_painting_tweaks.h"
+
+#include <QRegion>
+#include <QPainter>
+#include <QTransform>
+
+#include "kis_debug.h"
+
+
+namespace KisPaintingTweaks {
+
+QRegion safeClipRegion(const QPainter &painter)
+{
+ const QTransform t = painter.transform();
+
+ QRegion region = t.type() <= QTransform::TxScale ?
+ painter.clipRegion() :
+ QRegion(painter.clipBoundingRect().toAlignedRect());
+
+ if (region.rectCount() > 1000) {
+ qWarning() << "WARNING: KisPaintingTweaks::safeClipRegion: too many \
rectangles in the region!" << ppVar(region.rectCount()); + region = \
QRegion(painter.clipBoundingRect().toAlignedRect()); + }
+
+ return region;
+}
+
+QRect safeClipBoundingRect(const QPainter &painter)
+{
+ return painter.clipBoundingRect().toAlignedRect();
+}
+
+}
diff --git a/libs/global/kis_painting_tweaks.h b/libs/global/kis_painting_tweaks.h
new file mode 100644
index 0000000..274cbad
--- /dev/null
+++ b/libs/global/kis_painting_tweaks.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_PAINTING_TWEAKS_H
+#define __KIS_PAINTING_TWEAKS_H
+
+#include "kritaglobal_export.h"
+
+class QPainter;
+class QRegion;
+class QRect;
+
+namespace KisPaintingTweaks {
+
+ /**
+ * This is a workaround for QPainter::clipRegion() bug. When zoom
+ * is about 2000% and rotation is in a range[-5;5] degrees, the
+ * generated region will have about 20k+ regtangles inside. Their
+ * processing will be really slow. These functions fworkarounds
+ * the issue.
+ */
+ KRITAGLOBAL_EXPORT QRegion safeClipRegion(const QPainter &painter);
+
+ /**
+ * \see safeClipRegion()
+ */
+ KRITAGLOBAL_EXPORT QRect safeClipBoundingRect(const QPainter &painter);
+}
+
+#endif /* __KIS_PAINTING_TWEAKS_H */
diff --git a/plugins/flake/textshape/TextShape.cpp \
b/plugins/flake/textshape/TextShape.cpp index 65b5ac3..7fdda74 100644
--- a/plugins/flake/textshape/TextShape.cpp
+++ b/plugins/flake/textshape/TextShape.cpp
@@ -63,6 +63,9 @@
#include <QDebug>
+#include "kis_painting_tweaks.h"
+
+
TextShape::TextShape(KoInlineTextObjectManager *inlineTextObjectManager, \
KoTextRangeManager *textRangeManager) : KoShapeContainer(new \
KoTextShapeContainerModel()) , KoFrameShape(KoXmlNS::draw, "text-box")
@@ -137,7 +140,7 @@ void TextShape::paintComponent(QPainter &painter, const \
KoViewConverter &convert KoTextPage *page = m_pageProvider->page(this);
if (page) {
// this is used to not trigger repaints if layout during the painting is \
done
- m_paintRegion = painter.clipRegion();
+ m_paintRegion = KisPaintingTweaks::safeClipRegion(painter);
if (!m_textShapeData->rootArea()->page() || page->pageNumber() != \
m_textShapeData->rootArea()->page()->pageNumber()) {
m_textShapeData->rootArea()->setPage(page); // takes over ownership \
of the page } else {
diff --git a/plugins/flake/textshape/textlayout/KoTextLayoutArea_paint.cpp \
b/plugins/flake/textshape/textlayout/KoTextLayoutArea_paint.cpp index \
5d6860c..dbe749e 100644
--- a/plugins/flake/textshape/textlayout/KoTextLayoutArea_paint.cpp
+++ b/plugins/flake/textshape/textlayout/KoTextLayoutArea_paint.cpp
@@ -65,6 +65,7 @@
#include <QTextLayout>
#include <QTextCursor>
#include <QTime>
+#include "kis_painting_tweaks.h"
extern int qt_defaultDpiY();
Q_DECLARE_METATYPE(QTextDocument *)
@@ -91,7 +92,7 @@ void KoTextLayoutArea::paint(QPainter *painter, const \
KoTextDocumentLayout::Pain painter->translate(0, d->verticalAlignOffset);
painter->setPen(context.textContext.palette.color(QPalette::Text)); // for text \
that has no color.
- const QRegion clipRegion = painter->clipRegion(); // fetch after \
painter->translate so the clipRegion is correct + const QRegion clipRegion = \
KisPaintingTweaks::safeClipRegion(*painter); // fetch after painter->translate so the \
clipRegion is correct KoTextBlockBorderData *lastBorder = 0;
QRectF lastBorderRect;
diff --git a/plugins/flake/vectorshape/VectorShape.cpp \
b/plugins/flake/vectorshape/VectorShape.cpp index 6e227df..2a80a5c 100644
--- a/plugins/flake/vectorshape/VectorShape.cpp
+++ b/plugins/flake/vectorshape/VectorShape.cpp
@@ -57,6 +57,8 @@
#include "SvmParser.h"
#include "SvmPainterBackend.h"
+#include "kis_painting_tweaks.h"
+
// Comment out to get uncached painting, which is good for debugging
//#define VECTORSHAPE_PAINT_UNCACHED
@@ -247,7 +249,7 @@ void VectorShape::paint(QPainter &painter, const KoViewConverter \
&converter, KoS QImage *cache = render(converter, asynchronous, useCache);
if (cache) { // paint cached image
Q_ASSERT(!cache->isNull());
- QVector<QRect> clipRects = painter.clipRegion().rects();
+ QVector<QRect> clipRects = \
KisPaintingTweaks::safeClipRegion(painter).rects(); foreach (const QRect &rc, \
clipRects) { painter.drawImage(rc.topLeft(), *cache, rc);
}
_______________________________________________
Krita mailing list
kimageshop@kde.org
https://mail.kde.org/mailman/listinfo/kimageshop
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic