summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/composition/composition.cpp35
-rw-r--r--demos/composition/composition.h13
-rw-r--r--src/corelib/tools/qcontiguouscache.h35
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp4
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp127
-rw-r--r--tests/auto/qcontiguouscache/tst_qcontiguouscache.cpp12
6 files changed, 134 insertions, 92 deletions
diff --git a/demos/composition/composition.cpp b/demos/composition/composition.cpp
index e03f3e6..deca5dc 100644
--- a/demos/composition/composition.cpp
+++ b/demos/composition/composition.cpp
@@ -48,6 +48,8 @@
#include <QMouseEvent>
#include <qmath.h>
+const int animationInterval = 15; // update every 16 ms = ~60FPS
+
CompositionWidget::CompositionWidget(QWidget *parent)
: QWidget(parent)
{
@@ -236,6 +238,7 @@ CompositionRenderer::CompositionRenderer(QWidget *parent)
: ArthurFrame(parent)
{
m_animation_enabled = true;
+ m_animationTimer = startTimer(animationInterval);
#ifdef Q_WS_QWS
m_image = QPixmap(":res/composition/flower.jpg");
m_image.setAlphaChannel(QPixmap(":res/composition/flower_alpha.jpg"));
@@ -264,6 +267,20 @@ QRectF rectangle_around(const QPointF &p, const QSizeF &size = QSize(250, 200))
return rect;
}
+void CompositionRenderer::setAnimationEnabled(bool enabled)
+{
+ if (m_animation_enabled == enabled)
+ return;
+ m_animation_enabled = enabled;
+ if (enabled) {
+ Q_ASSERT(!m_animationTimer);
+ m_animationTimer = startTimer(animationInterval);
+ } else {
+ killTimer(m_animationTimer);
+ m_animationTimer = 0;
+ }
+}
+
void CompositionRenderer::updateCirclePos()
{
if (m_current_object != NoObject)
@@ -471,10 +488,6 @@ void CompositionRenderer::paint(QPainter *painter)
painter->drawImage(0, 0, m_buffer);
#endif
}
-
- if (m_animation_enabled && m_current_object == NoObject) {
- updateCirclePos();
- }
}
void CompositionRenderer::mousePressEvent(QMouseEvent *e)
@@ -489,6 +502,10 @@ void CompositionRenderer::mousePressEvent(QMouseEvent *e)
} else {
m_current_object = NoObject;
}
+ if (m_animation_enabled) {
+ killTimer(m_animationTimer);
+ m_animationTimer = 0;
+ }
}
void CompositionRenderer::mouseMoveEvent(QMouseEvent *e)
@@ -500,7 +517,15 @@ void CompositionRenderer::mouseReleaseEvent(QMouseEvent *)
{
m_current_object = NoObject;
- if (m_animation_enabled)
+ if (m_animation_enabled) {
+ Q_ASSERT(!m_animationTimer);
+ m_animationTimer = startTimer(animationInterval);
+ }
+}
+
+void CompositionRenderer::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_animationTimer)
updateCirclePos();
}
diff --git a/demos/composition/composition.h b/demos/composition/composition.h
index 1123531..f5a9fc3 100644
--- a/demos/composition/composition.h
+++ b/demos/composition/composition.h
@@ -109,10 +109,6 @@ public:
void paint(QPainter *);
- void mousePressEvent(QMouseEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void mouseReleaseEvent(QMouseEvent *);
-
void setCirclePos(const QPointF &pos);
QSize sizeHint() const { return QSize(500, 400); }
@@ -121,6 +117,12 @@ public:
int circleColor() const { return m_circle_hue; }
int circleAlpha() const { return m_circle_alpha; }
+protected:
+ void mousePressEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void timerEvent(QTimerEvent *);
+
public slots:
void setClearMode() { m_composition_mode = QPainter::CompositionMode_Clear; update(); }
void setSourceMode() { m_composition_mode = QPainter::CompositionMode_Source; update(); }
@@ -150,7 +152,7 @@ public slots:
void setCircleAlpha(int alpha) { m_circle_alpha = alpha; update(); }
void setCircleColor(int hue) { m_circle_hue = hue; update(); }
- void setAnimationEnabled(bool enabled) { m_animation_enabled = enabled; update(); }
+ void setAnimationEnabled(bool enabled);
private:
void updateCirclePos();
@@ -177,6 +179,7 @@ private:
ObjectType m_current_object;
bool m_animation_enabled;
+ int m_animationTimer;
#ifdef QT_OPENGL_SUPPORT
QGLPixelBuffer *m_pbuffer;
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index 1f7fdb2..aa5603d 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -221,22 +221,29 @@ void QContiguousCache<T>::setCapacity(int asize)
x.d->alloc = asize;
x.d->count = qMin(d->count, asize);
x.d->offset = d->offset + d->count - x.d->count;
- x.d->start = x.d->offset % x.d->alloc;
- T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc;
- T *src = p->array + (d->start + d->count-1) % d->alloc;
+ if(asize)
+ x.d->start = x.d->offset % x.d->alloc;
+ else
+ x.d->start = 0;
+
int oldcount = x.d->count;
- while (oldcount--) {
- if (QTypeInfo<T>::isComplex) {
- new (dest) T(*src);
- } else {
- *dest = *src;
+ if(oldcount)
+ {
+ T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc;
+ T *src = p->array + (d->start + d->count-1) % d->alloc;
+ while (oldcount--) {
+ if (QTypeInfo<T>::isComplex) {
+ new (dest) T(*src);
+ } else {
+ *dest = *src;
+ }
+ if (dest == x.p->array)
+ dest = x.p->array + x.d->alloc;
+ dest--;
+ if (src == p->array)
+ src = p->array + d->alloc;
+ src--;
}
- if (dest == x.p->array)
- dest = x.p->array + x.d->alloc;
- dest--;
- if (src == p->array)
- src = p->array + d->alloc;
- src--;
}
/* free old */
free(p);
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 96d2435..86aaa78 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -5132,6 +5132,8 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
}
/*!
+ \obsolete
+
Paints the given \a items using the provided \a painter, after the
background has been drawn, and before the foreground has been
drawn. All painting is done in \e scene coordinates. Before
@@ -5154,7 +5156,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
\snippet doc/src/snippets/graphicssceneadditemsnippet.cpp 0
- \obsolete Since Qt 4.6, this function is not called anymore unless
+ Since Qt 4.6, this function is not called anymore unless
the QGraphicsView::IndirectPainting flag is given as an Optimization
flag.
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index 1dba914..6ac64d3 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -63,36 +63,36 @@ QT_BEGIN_NAMESPACE
* colorMask must have 0x00ff00ff on each 32 bits component
* half must have the value 128 (0x80) for each 32 bits compnent
*/
-Q_STATIC_INLINE_FUNCTION __m128i BYTE_MUL_SSE2(const __m128i pixelVector, const __m128i alphaChannel, const __m128i colorMask, const __m128i half)
-{
- // 1. separate the colors in 2 vectors so each color is on 16 bits
- // (in order to be multiplied by the alpha
- // each 32 bit of dstVectorAG are in the form 0x00AA00GG
- // each 32 bit of dstVectorRB are in the form 0x00RR00BB
- __m128i pixelVectorAG = _mm_srli_epi16(pixelVector, 8);
- __m128i pixelVectorRB = _mm_and_si128(pixelVector, colorMask);
-
- // 2. multiply the vectors by the alpha channel
- pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel);
- pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel);
-
- // 3. devide by 255, that's the tricky part.
- // we do it like for BYTE_MUL(), with bit shift: X/255 ~= (X + X/256 + rounding)/256
- /// so first (X + X/256 + rounding)
- pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8));
- pixelVectorRB = _mm_add_epi16(pixelVectorRB, half);
- pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8));
- pixelVectorAG = _mm_add_epi16(pixelVectorAG, half);
-
- /// second devide by 256
- pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8);
- /// for AG, we could >> 8 to divide followed by << 8 to put the
- /// bytes in the correct position. By masking instead, we execute
- /// only one instruction
- pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG);
-
- // 4. combine the 2 pairs of colors
- return _mm_or_si128(pixelVectorAG, pixelVectorRB);
+#define BYTE_MUL_SSE2(result, pixelVector, alphaChannel, colorMask, half) \
+{ \
+ /* 1. separate the colors in 2 vectors so each color is on 16 bits \
+ (in order to be multiplied by the alpha \
+ each 32 bit of dstVectorAG are in the form 0x00AA00GG \
+ each 32 bit of dstVectorRB are in the form 0x00RR00BB */\
+ __m128i pixelVectorAG = _mm_srli_epi16(pixelVector, 8); \
+ __m128i pixelVectorRB = _mm_and_si128(pixelVector, colorMask); \
+ \
+ /* 2. multiply the vectors by the alpha channel */\
+ pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel); \
+ pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel); \
+ \
+ /* 3. devide by 255, that's the tricky part. \
+ we do it like for BYTE_MUL(), with bit shift: X/255 ~= (X + X/256 + rounding)/256 */ \
+ /** so first (X + X/256 + rounding) */\
+ pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); \
+ pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); \
+ pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); \
+ pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); \
+ \
+ /** second devide by 256 */\
+ pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); \
+ /** for AG, we could >> 8 to divide followed by << 8 to put the \
+ bytes in the correct position. By masking instead, we execute \
+ only one instruction */\
+ pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); \
+ \
+ /* 4. combine the 2 pairs of colors */ \
+ result = _mm_or_si128(pixelVectorAG, pixelVectorRB); \
}
/*
@@ -101,34 +101,29 @@ Q_STATIC_INLINE_FUNCTION __m128i BYTE_MUL_SSE2(const __m128i pixelVector, const
* colorMask must have 0x00ff00ff on each 32 bits component
* half must have the value 128 (0x80) for each 32 bits compnent
*/
-Q_STATIC_INLINE_FUNCTION __m128i INTERPOLATE_PIXEL_255_SSE2(const __m128i srcVector,
- const __m128i dstVector,
- const __m128i alphaChannel,
- const __m128i oneMinusAlphaChannel ,
- const __m128i colorMask,
- const __m128i half) {
- // interpolate AG
- __m128i srcVectorAG = _mm_srli_epi16(srcVector, 8);
- __m128i dstVectorAG = _mm_srli_epi16(dstVector, 8);
- __m128i srcVectorAGalpha = _mm_mullo_epi16(srcVectorAG, alphaChannel);
- __m128i dstVectorAGoneMinusAlphalpha = _mm_mullo_epi16(dstVectorAG, oneMinusAlphaChannel);
- __m128i finalAG = _mm_add_epi16(srcVectorAGalpha, dstVectorAGoneMinusAlphalpha);
- finalAG = _mm_add_epi16(finalAG, _mm_srli_epi16(finalAG, 8));
- finalAG = _mm_add_epi16(finalAG, half);
- finalAG = _mm_andnot_si128(colorMask, finalAG);
-
- // interpolate RB
- __m128i srcVectorRB = _mm_and_si128(srcVector, colorMask);
- __m128i dstVectorRB = _mm_and_si128(dstVector, colorMask);
- __m128i srcVectorRBalpha = _mm_mullo_epi16(srcVectorRB, alphaChannel);
- __m128i dstVectorRBoneMinusAlphalpha = _mm_mullo_epi16(dstVectorRB, oneMinusAlphaChannel);
- __m128i finalRB = _mm_add_epi16(srcVectorRBalpha, dstVectorRBoneMinusAlphalpha);
- finalRB = _mm_add_epi16(finalRB, _mm_srli_epi16(finalRB, 8));
- finalRB = _mm_add_epi16(finalRB, half);
- finalRB = _mm_srli_epi16(finalRB, 8);
-
- // combine
- return _mm_or_si128(finalAG, finalRB);
+#define INTERPOLATE_PIXEL_255_SSE2(result, srcVector, dstVector, alphaChannel, oneMinusAlphaChannel, colorMask, half) { \
+ /* interpolate AG */\
+ __m128i srcVectorAG = _mm_srli_epi16(srcVector, 8); \
+ __m128i dstVectorAG = _mm_srli_epi16(dstVector, 8); \
+ __m128i srcVectorAGalpha = _mm_mullo_epi16(srcVectorAG, alphaChannel); \
+ __m128i dstVectorAGoneMinusAlphalpha = _mm_mullo_epi16(dstVectorAG, oneMinusAlphaChannel); \
+ __m128i finalAG = _mm_add_epi16(srcVectorAGalpha, dstVectorAGoneMinusAlphalpha); \
+ finalAG = _mm_add_epi16(finalAG, _mm_srli_epi16(finalAG, 8)); \
+ finalAG = _mm_add_epi16(finalAG, half); \
+ finalAG = _mm_andnot_si128(colorMask, finalAG); \
+ \
+ /* interpolate RB */\
+ __m128i srcVectorRB = _mm_and_si128(srcVector, colorMask); \
+ __m128i dstVectorRB = _mm_and_si128(dstVector, colorMask); \
+ __m128i srcVectorRBalpha = _mm_mullo_epi16(srcVectorRB, alphaChannel); \
+ __m128i dstVectorRBoneMinusAlphalpha = _mm_mullo_epi16(dstVectorRB, oneMinusAlphaChannel); \
+ __m128i finalRB = _mm_add_epi16(srcVectorRBalpha, dstVectorRBoneMinusAlphalpha); \
+ finalRB = _mm_add_epi16(finalRB, _mm_srli_epi16(finalRB, 8)); \
+ finalRB = _mm_add_epi16(finalRB, half); \
+ finalRB = _mm_srli_epi16(finalRB, 8); \
+ \
+ /* combine */\
+ result = _mm_or_si128(finalAG, finalRB); \
}
void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
@@ -165,7 +160,8 @@ void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
alphaChannel = _mm_sub_epi16(one, alphaChannel);
const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]);
- const __m128i destMultipliedByOneMinusAlpha = BYTE_MUL_SSE2(dstVector, alphaChannel, colorMask, half);
+ __m128i destMultipliedByOneMinusAlpha;
+ BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half);
// result = s + d * (1-alpha)
const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha);
@@ -197,14 +193,15 @@ void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
for (; x < w-3; x += 4) {
__m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) {
- srcVector = BYTE_MUL_SSE2(srcVector, constAlphaVector, colorMask, half);
+ BYTE_MUL_SSE2(srcVector, srcVector, constAlphaVector, colorMask, half);
__m128i alphaChannel = _mm_srli_epi32(srcVector, 24);
alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16));
alphaChannel = _mm_sub_epi16(one, alphaChannel);
const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]);
- const __m128i destMultipliedByOneMinusAlpha = BYTE_MUL_SSE2(dstVector, alphaChannel, colorMask, half);
+ __m128i destMultipliedByOneMinusAlpha;
+ BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half);
const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha);
_mm_storeu_si128((__m128i *)&dst[x], result);
@@ -252,12 +249,8 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
__m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]);
if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) {
const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]);
- const __m128i result = INTERPOLATE_PIXEL_255_SSE2(srcVector,
- dstVector,
- constAlphaVector,
- oneMinusConstAlpha,
- colorMask,
- half);
+ __m128i result;
+ INTERPOLATE_PIXEL_255_SSE2(result, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half);
_mm_storeu_si128((__m128i *)&dst[x], result);
}
}
diff --git a/tests/auto/qcontiguouscache/tst_qcontiguouscache.cpp b/tests/auto/qcontiguouscache/tst_qcontiguouscache.cpp
index 5a23274..f64e815 100644
--- a/tests/auto/qcontiguouscache/tst_qcontiguouscache.cpp
+++ b/tests/auto/qcontiguouscache/tst_qcontiguouscache.cpp
@@ -71,6 +71,8 @@ private slots:
void contiguousCacheBenchmark();
void setCapacity();
+
+ void zeroCapacity();
};
QTEST_MAIN(tst_QContiguousCache)
@@ -476,4 +478,14 @@ void tst_QContiguousCache::setCapacity()
}
}
+void tst_QContiguousCache::zeroCapacity()
+{
+ QContiguousCache<int> contiguousCache;
+ QCOMPARE(contiguousCache.capacity(),0);
+ contiguousCache.setCapacity(10);
+ QCOMPARE(contiguousCache.capacity(),10);
+ contiguousCache.setCapacity(0);
+ QCOMPARE(contiguousCache.capacity(),0);
+}
+
#include "tst_qcontiguouscache.moc"