summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2010-06-01 11:31:18 (GMT)
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2010-06-01 12:03:17 (GMT)
commitff57057bc6844eb3c10ab0eadff292a10ef493f8 (patch)
tree638f0272653e58cf0b29e510f40272fa7e797ede /src/gui
parent6750d0dcbf5a2e88fab2e127dc3e057f0d68bf71 (diff)
downloadQt-ff57057bc6844eb3c10ab0eadff292a10ef493f8.zip
Qt-ff57057bc6844eb3c10ab0eadff292a10ef493f8.tar.gz
Qt-ff57057bc6844eb3c10ab0eadff292a10ef493f8.tar.bz2
Speed up QStaticText with affine transformation on GL2 engine
Since the OpenGL2 paint engine supports transforming the prerendered glyphs rather than rasterizing the glyphs with the transformation applied, we don't need to recalculate the QStaticText layout whenever the transformation changes. This means that we can do fast animated transforms for QStaticText on this paint engine. A quick test yields something like 100x speed-up on Windows. This also give visually better results, as we previously would animate the hinting of the glyphs, thus causing jittering. The autotest has been updated to reflect the fact that drawText() and drawStaticText() now go through identical paths on GL, also when transforms are set on the painter. However, the scale was changed in one test, because it was so great that drawText() would fall back to paths. With QStaticText the idea is speed, so you'll get a poor, but fast result instead, which is better than tricking people. Reviewed-by: Samuel
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/painting/qpainter.cpp23
-rw-r--r--src/gui/text/qstatictext.cpp37
-rw-r--r--src/gui/text/qstatictext_p.h7
3 files changed, 44 insertions, 23 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 657229a..4596754 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -5855,14 +5855,24 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
return;
}
+ if (d->extended->type() == QPaintEngine::OpenGL2 && !staticText_d->untransformedCoordinates) {
+ staticText_d->untransformedCoordinates = true;
+ staticText_d->needsRelayout = true;
+ } else if (d->extended->type() != QPaintEngine::OpenGL2 && staticText_d->untransformedCoordinates) {
+ staticText_d->untransformedCoordinates = false;
+ staticText_d->needsRelayout = true;
+ }
+
// Don't recalculate entire layout because of translation, rather add the dx and dy
// into the position to move each text item the correct distance.
- QPointF transformedPosition = topLeftPosition * d->state->matrix;
- QTransform matrix = d->state->matrix;
+ QPointF transformedPosition = topLeftPosition;
+ if (!staticText_d->untransformedCoordinates)
+ transformedPosition = transformedPosition * d->state->matrix;
+ QTransform oldMatrix;
// The translation has been applied to transformedPosition. Remove translation
// component from matrix.
- if (d->state->matrix.isTranslating()) {
+ if (d->state->matrix.isTranslating() && !staticText_d->untransformedCoordinates) {
qreal m11 = d->state->matrix.m11();
qreal m12 = d->state->matrix.m12();
qreal m13 = d->state->matrix.m13();
@@ -5871,6 +5881,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
qreal m23 = d->state->matrix.m23();
qreal m33 = d->state->matrix.m33();
+ oldMatrix = d->state->matrix;
d->state->matrix.setMatrix(m11, m12, m13,
m21, m22, m23,
0.0, 0.0, m33);
@@ -5879,7 +5890,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
// If the transform is not identical to the text transform,
// we have to relayout the text (for other transformations than plain translation)
bool staticTextNeedsReinit = staticText_d->needsRelayout;
- if (staticText_d->matrix != d->state->matrix) {
+ if (!staticText_d->untransformedCoordinates && staticText_d->matrix != d->state->matrix) {
staticText_d->matrix = d->state->matrix;
staticTextNeedsReinit = true;
}
@@ -5918,8 +5929,8 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
if (currentColor != oldPen.color())
setPen(oldPen);
- if (matrix.isTranslating())
- d->state->matrix = matrix;
+ if (!staticText_d->untransformedCoordinates && oldMatrix.isTranslating())
+ d->state->matrix = oldMatrix;
}
/*!
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index 84c1d96..10870aa 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -115,10 +115,12 @@ QT_BEGIN_NAMESPACE
Qt::RichText.
If it's the first time the static text is drawn, or if the static text, or the painter's font
- or matrix have been altered since the last time it was drawn, the text's layout has to be
- recalculated. This will impose an overhead on the QPainter::drawStaticText() call where the
- relayout occurs. To avoid this overhead in the paint event, you can call prepare() ahead of
- time to ensure that the layout is calculated.
+ has been altered since the last time it was drawn, the text's layout has to be
+ recalculated. On some paint engines, changing the matrix of the painter will also cause the
+ layout to be recalculated. In particular, this will happen for any engine except for the
+ OpenGL2 paint engine. Recalculating the layout will impose an overhead on the
+ QPainter::drawStaticText() call where it occurs. To avoid this overhead in the paint event, you
+ can call prepare() ahead of time to ensure that the layout is calculated.
\sa QPainter::drawText(), QPainter::drawStaticText(), QTextLayout, QTextDocument
*/
@@ -188,8 +190,9 @@ void QStaticText::detach()
When drawStaticText() is called, the layout of the QStaticText will be recalculated if any part
of the QStaticText object has changed since the last time it was drawn. It will also be
- recalculated if the painter's font or matrix are not the same as when the QStaticText was last
- drawn.
+ recalculated if the painter's font is not the same as when the QStaticText was last drawn, or,
+ on any other paint engine than the OpenGL2 engine, if the painter's matrix has been altered
+ since the static text was last drawn.
To avoid the overhead of creating the layout the first time you draw the QStaticText after
making changes, you can use the prepare() function and pass in the \a matrix and \a font you
@@ -364,14 +367,16 @@ QSizeF QStaticText::size() const
QStaticTextPrivate::QStaticTextPrivate()
: textWidth(-1.0), items(0), itemCount(0), glyphPool(0), positionPool(0), charPool(0),
- needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText)
+ needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText),
+ untransformedCoordinates(false)
{
}
QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other)
: text(other.text), font(other.font), textWidth(other.textWidth), matrix(other.matrix),
items(0), itemCount(0), glyphPool(0), positionPool(0), charPool(0), needsRelayout(true),
- useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat)
+ useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat),
+ untransformedCoordinates(other.untransformedCoordinates)
{
}
@@ -396,8 +401,9 @@ namespace {
class DrawTextItemRecorder: public QPaintEngine
{
public:
- DrawTextItemRecorder(bool useBackendOptimizations, int numChars)
- : m_dirtyPen(false), m_useBackendOptimizations(useBackendOptimizations)
+ DrawTextItemRecorder(bool untransformedCoordinates, bool useBackendOptimizations, int numChars)
+ : m_dirtyPen(false), m_useBackendOptimizations(useBackendOptimizations),
+ m_untransformedCoordinates(untransformedCoordinates)
{
}
@@ -423,7 +429,7 @@ namespace {
if (m_dirtyPen)
currentItem.color = state->pen().color();
- QTransform matrix = state->transform();
+ QTransform matrix = m_untransformedCoordinates ? QTransform() : state->transform();
matrix.translate(position.x(), position.y());
QVarLengthArray<glyph_t> glyphs;
@@ -486,14 +492,17 @@ namespace {
bool m_dirtyPen;
bool m_useBackendOptimizations;
+ bool m_untransformedCoordinates;
};
class DrawTextItemDevice: public QPaintDevice
{
public:
- DrawTextItemDevice(bool useBackendOptimizations, int numChars)
+ DrawTextItemDevice(bool untransformedCoordinates, bool useBackendOptimizations,
+ int numChars)
{
- m_paintEngine = new DrawTextItemRecorder(useBackendOptimizations, numChars);
+ m_paintEngine = new DrawTextItemRecorder(untransformedCoordinates,
+ useBackendOptimizations, numChars);
}
~DrawTextItemDevice()
@@ -629,7 +638,7 @@ void QStaticTextPrivate::init()
position = QPointF(0, 0);
- DrawTextItemDevice device(useBackendOptimizations, text.size());
+ DrawTextItemDevice device(untransformedCoordinates, useBackendOptimizations, text.size());
{
QPainter painter(&device);
painter.setFont(font);
diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h
index 2ab5579..1a96291 100644
--- a/src/gui/text/qstatictext_p.h
+++ b/src/gui/text/qstatictext_p.h
@@ -148,9 +148,10 @@ public:
QFixedPoint *positionPool; // 4 bytes per text
QChar *charPool; // 4 bytes per text
- unsigned char needsRelayout : 1;
- unsigned char useBackendOptimizations : 1; // 1 byte per text
- unsigned char textFormat : 2;
+ unsigned char needsRelayout : 1; // 1 byte per text
+ unsigned char useBackendOptimizations : 1;
+ unsigned char textFormat : 2;
+ unsigned char untransformedCoordinates : 1;
// ================
// 167 bytes per text