diff options
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/painting.pri | 21 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_p.h | 140 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_sse2.cpp | 41 | ||||
-rw-r--r-- | src/gui/painting/qdrawingprimitive_sse2_p.h | 8 | ||||
-rw-r--r-- | src/gui/painting/qgraphicssystem_runtime.cpp | 109 | ||||
-rw-r--r-- | src/gui/painting/qgraphicssystem_runtime_p.h | 17 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_x11.cpp | 22 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 65 | ||||
-rw-r--r-- | src/gui/painting/qwindowsurface_s60.cpp | 12 |
11 files changed, 206 insertions, 233 deletions
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 4023f65..dfa4a48 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -246,23 +246,8 @@ symbian { QMAKE_CXXFLAGS.ARMCC *= -O3 } -neon:*-g++* { - DEFINES += QT_HAVE_NEON - HEADERS += painting/qdrawhelper_neon_p.h - SOURCES += painting/qdrawhelper_neon.cpp - QMAKE_CXXFLAGS *= -mfpu=neon - - DRAWHELPER_NEON_ASM_FILES = ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S - - neon_compiler.commands = $$QMAKE_CXX -c - neon_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} - neon_compiler.dependency_type = TYPE_C - neon_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} - neon_compiler.input = DRAWHELPER_NEON_ASM_FILES - neon_compiler.variable_out = OBJECTS - neon_compiler.name = compiling[neon] ${QMAKE_FILE_IN} - silent:neon_compiler.commands = @echo compiling[neon] ${QMAKE_FILE_IN} && $$neon_compiler.commands - QMAKE_EXTRA_COMPILERS += neon_compiler -} +NEON_SOURCES += painting/qdrawhelper_neon.cpp +NEON_HEADERS += painting/qdrawhelper_neon_p.h +NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S include($$PWD/../../3rdparty/zlib_dependency.pri) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index f5641a4..eb92d3f 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -7938,8 +7938,10 @@ void qInitDrawhelperAsm() uint const_alpha); extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha); extern void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha); + extern void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha); functionForModeAsm[0] = comp_func_SourceOver_sse2; + functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_sse2; functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2; functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2; diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 1a87127..d04c70d 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -314,18 +314,61 @@ struct QSpanData void adjustSpanMethods(); }; +#if defined(Q_CC_RVCT) +# pragma push +# pragma arm +#endif +Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) { + uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; + t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; + t &= 0xff00ff; -Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16(uint x, uint a) { - a += 1; - uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0; - t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f; - return t; + x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; + x = (x + ((x >> 8) & 0xff00ff) + 0x800080); + x &= 0xff00ff00; + x |= t; + return x; } +#if defined(Q_CC_RVCT) +# pragma pop +#endif -Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) { - uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0; - t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f; - return t; +#if QT_POINTER_SIZE == 8 // 64-bit versions + +Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { + quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; + t += (((quint64(y)) | ((quint64(y)) << 24)) & 0x00ff00ff00ff00ff) * b; + t >>= 8; + t &= 0x00ff00ff00ff00ff; + return (uint(t)) | (uint(t >> 24)); +} + +Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) { + quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; + t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8; + t &= 0x00ff00ff00ff00ff; + return (uint(t)) | (uint(t >> 24)); +} + +Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) { + uint a = x >> 24; + quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; + t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8; + t &= 0x000000ff00ff00ff; + return (uint(t)) | (uint(t >> 24)) | (a << 24); +} + +#else // 32-bit versions + +Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { + uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; + t >>= 8; + t &= 0xff00ff; + + x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; + x &= 0xff00ff00; + x |= t; + return x; } #if defined(Q_CC_RVCT) @@ -359,6 +402,21 @@ Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) { x |= t | (a << 24); return x; } +#endif + + +Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16(uint x, uint a) { + a += 1; + uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0; + t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f; + return t; +} + +Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) { + uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0; + t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f; + return t; +} #define INV_PREMUL(p) \ (qAlpha(p) == 0 ? 0 : \ @@ -1847,70 +1905,6 @@ inline int qBlue565(quint16 rgb) { return (b << 3) | (b >> 2); } -#if 1 -Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { - uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; - t >>= 8; - t &= 0xff00ff; - - x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; - x &= 0xff00ff00; - x |= t; - return x; -} - -#if defined(Q_CC_RVCT) -# pragma push -# pragma arm -#endif -Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) { - uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; - t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; - t &= 0xff00ff; - - x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; - x = (x + ((x >> 8) & 0xff00ff) + 0x800080); - x &= 0xff00ff00; - x |= t; - return x; -} -#if defined(Q_CC_RVCT) -# pragma pop -#endif -#else -// possible implementation for 64 bit -Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { - ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a; - t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b; - t >>= 8; - t &= 0x00ff00ff00ff00ff; - return (uint(t)) | (uint(t >> 24)); -} - -Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) { - ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a; - t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b; - t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080); - t &= 0x00ff00ff00ff00ff; - return (uint(t)) | (uint(t >> 24)); -} - -Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) { - ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a; - t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080); - t &= 0x00ff00ff00ff00ff; - return (uint(t)) | (uint(t >> 24)); -} - -Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) { - uint a = x >> 24; - ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a; - t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080); - t &= 0x00ff00ff00ff00ff; - return (uint(t)) | (uint(t >> 24)) | 0xff000000; -} -#endif - const uint qt_bayer_matrix[16][16] = { { 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc, 0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff}, diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index e090ae5..22c0384 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -112,9 +112,7 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, int x = 0; // First, align dest to 16 bytes: - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3; - const int prologLength = qMin(w, offsetToAlignOn16Bytes); - for (; x < prologLength; ++x) { + ALIGNMENT_PROLOGUE_16BYTES(dst, x, w) { quint32 s = src[x]; s = BYTE_MUL(s, const_alpha); dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha); @@ -182,12 +180,10 @@ inline int comp_func_Plus_one_pixel(uint d, const uint s) void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha) { int x = 0; - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3; - const int prologLength = qMin(length, offsetToAlignOn16Bytes); if (const_alpha == 255) { // 1) Prologue: align destination on 16 bytes - for (; x < prologLength; ++x) + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) dst[x] = comp_func_Plus_one_pixel(dst[x], src[x]); // 2) composition with SSE2 @@ -208,7 +204,7 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin const __m128i oneMinusConstAlpha = _mm_set1_epi16(one_minus_const_alpha); // 1) Prologue: align destination on 16 bytes - for (; x < prologLength; ++x) + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha); const __m128i half = _mm_set1_epi16(0x80); @@ -229,6 +225,37 @@ void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uin } } +void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha) +{ + if (const_alpha == 255) { + ::memcpy(dst, src, length * sizeof(uint)); + } else { + const int ialpha = 255 - const_alpha; + + int x = 0; + + // 1) prologue, align on 16 bytes + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) + dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha); + + // 2) interpolate pixels with SSE2 + const __m128i half = _mm_set1_epi16(0x80); + const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); + const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); + const __m128i oneMinusConstAlpha = _mm_set1_epi16(ialpha); + for (; x < length - 3; x += 4) { + const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); + __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); + INTERPOLATE_PIXEL_255_SSE2(dstVector, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half) + _mm_store_si128((__m128i *)&dst[x], dstVector); + } + + // 3) Epilogue + for (; x < length; ++x) + dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha); + } +} + void qt_memfill32_sse2(quint32 *dest, quint32 value, int count) { if (count < 7) { diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index 18355c2..d8f6bf5 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -143,9 +143,7 @@ QT_BEGIN_NAMESPACE int x = 0; \ \ /* First, get dst aligned. */ \ - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;\ - const int prologLength = qMin(length, offsetToAlignOn16Bytes);\ - for (; x < prologLength; ++x) { \ + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \ uint s = src[x]; \ if (s >= 0xff000000) \ dst[x] = s; \ @@ -202,9 +200,7 @@ QT_BEGIN_NAMESPACE { \ int x = 0; \ \ - const int offsetToAlignOn16Bytes = (4 - ((reinterpret_cast<quintptr>(dst) >> 2) & 0x3)) & 0x3;\ - const int prologLength = qMin(length, offsetToAlignOn16Bytes);\ - for (; x < prologLength; ++x) { \ + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \ quint32 s = src[x]; \ if (s != 0) { \ s = BYTE_MUL(s, const_alpha); \ diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp index 3438137..2828e9d 100644 --- a/src/gui/painting/qgraphicssystem_runtime.cpp +++ b/src/gui/painting/qgraphicssystem_runtime.cpp @@ -53,10 +53,8 @@ QT_BEGIN_NAMESPACE static int qt_pixmap_serial = 0; #define READBACK(f) \ - m_graphicsSystem->decreaseMemoryUsage(memoryUsage()); \ f \ - readBackInfo(); \ - m_graphicsSystem->increaseMemoryUsage(memoryUsage()); \ + readBackInfo(); class QDeferredGraphicsSystemChange : public QObject @@ -252,16 +250,8 @@ QPixmapData* QRuntimePixmapData::runtimeData() const return m_data; } -uint QRuntimePixmapData::memoryUsage() const -{ - if(is_null || d == 0) - return 0; - return w * h * (d / 8); -} - - QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window) - : QWindowSurface(window), m_windowSurface(0), m_pendingWindowSurface(0), m_graphicsSystem(gs) + : QWindowSurface(window), m_graphicsSystem(gs) { } @@ -269,7 +259,6 @@ QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, Q QRuntimeWindowSurface::~QRuntimeWindowSurface() { m_graphicsSystem->removeWindowSurface(this); - delete m_windowSurface; } QPaintDevice *QRuntimeWindowSurface::paintDevice() @@ -288,16 +277,13 @@ void QRuntimeWindowSurface::flush(QWidget *widget, const QRegion ®ion, #ifdef QT_DEBUG qDebug() << "QRuntimeWindowSurface::flush() - destroy pending window surface"; #endif - delete m_pendingWindowSurface; - m_pendingWindowSurface = 0; + m_pendingWindowSurface.reset(); } } void QRuntimeWindowSurface::setGeometry(const QRect &rect) { - m_graphicsSystem->decreaseMemoryUsage(memoryUsage()); m_windowSurface->setGeometry(rect); - m_graphicsSystem->increaseMemoryUsage(memoryUsage()); } bool QRuntimeWindowSurface::scroll(const QRegion &area, int dx, int dy) @@ -330,27 +316,21 @@ QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const return m_windowSurface->offset(widget); } -uint QRuntimeWindowSurface::memoryUsage() const -{ - QPaintDevice *pdev = m_windowSurface->paintDevice(); - if (pdev && pdev->depth() != 0) - return pdev->width() * pdev->height() * (pdev->depth()/8); - - return 0; -} - QRuntimeGraphicsSystem::QRuntimeGraphicsSystem() - : m_memoryUsage(0), m_windowSurfaceDestroyPolicy(DestroyImmediately), - m_graphicsSystem(0), m_graphicsSystemChangeMemoryLimit(0) + : m_windowSurfaceDestroyPolicy(DestroyImmediately), + m_graphicsSystem(0) { QApplicationPrivate::graphics_system_name = QLatin1String("runtime"); QApplicationPrivate::runtime_graphics_system = true; +#ifdef QT_DEFAULT_RUNTIME_SYSTEM + m_graphicsSystemName = QLatin1String(QT_DEFAULT_RUNTIME_SYSTEM); + if (m_graphicsSystemName.isNull()) +#endif + m_graphicsSystemName = QLatin1String("raster"); + #ifdef Q_OS_SYMBIAN - m_graphicsSystemName = QLatin1String("openvg"); m_windowSurfaceDestroyPolicy = DestroyAfterFirstFlush; -#else - m_graphicsSystemName = QLatin1String("raster"); #endif m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName); @@ -373,51 +353,30 @@ QWindowSurface *QRuntimeGraphicsSystem::createWindowSurface(QWidget *widget) con { Q_ASSERT(m_graphicsSystem); QRuntimeWindowSurface *rtSurface = new QRuntimeWindowSurface(this, widget); - rtSurface->m_windowSurface = m_graphicsSystem->createWindowSurface(widget); + rtSurface->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget)); widget->setWindowSurface(rtSurface); m_windowSurfaces << rtSurface; - increaseMemoryUsage(rtSurface->memoryUsage()); return rtSurface; } -/*! - Sets graphics system when resource memory consumption is under /a memoryUsageLimit. -*/ -void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name, uint memoryUsageLimit) -{ -#ifdef QT_DEBUG - qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( "<< name <<", " << memoryUsageLimit << ")"; - qDebug() << " current approximated graphics system memory usage " << memoryUsage() << " bytes"; -#endif - if (memoryUsage() >= memoryUsageLimit) { - m_graphicsSystemChangeMemoryLimit = memoryUsageLimit; - m_pendingGraphicsSystemName = name; - } else { - setGraphicsSystem(name); - } -} - void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name) { if (m_graphicsSystemName == name) return; #ifdef QT_DEBUG qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )"; - qDebug() << " current approximated graphics system memory usage "<< memoryUsage() << " bytes"; #endif - delete m_graphicsSystem; + QGraphicsSystem *oldSystem = m_graphicsSystem; m_graphicsSystem = QGraphicsSystemFactory::create(name); m_graphicsSystemName = name; Q_ASSERT(m_graphicsSystem); - m_graphicsSystemChangeMemoryLimit = 0; m_pendingGraphicsSystemName = QString(); for (int i = 0; i < m_pixmapDatas.size(); ++i) { QRuntimePixmapData *proxy = m_pixmapDatas.at(i); QPixmapData *newData = m_graphicsSystem->createPixmapData(proxy->m_data); - // ### TODO Optimize. Openvg and s60raster graphics systems could switch internal ARGB32_PRE QImage buffers. newData->fromImage(proxy->m_data->toImage(), Qt::NoOpaqueDetection); delete proxy->m_data; proxy->m_data = newData; @@ -428,58 +387,26 @@ void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name) QRuntimeWindowSurface *proxy = m_windowSurfaces.at(i); QWidget *widget = proxy->m_windowSurface->window(); - if(m_windowSurfaceDestroyPolicy == DestroyImmediately) { - delete proxy->m_windowSurface; - proxy->m_pendingWindowSurface = 0; - } else { - proxy->m_pendingWindowSurface = proxy->m_windowSurface; - } + if(m_windowSurfaceDestroyPolicy == DestroyAfterFirstFlush) + proxy->m_pendingWindowSurface.reset(proxy->m_windowSurface.take()); - proxy->m_windowSurface = m_graphicsSystem->createWindowSurface(widget); + proxy->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget)); qt_widget_private(widget)->invalidateBuffer(widget->rect()); } + + delete oldSystem; } void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const { int index = m_pixmapDatas.lastIndexOf(pixmapData); m_pixmapDatas.removeAt(index); - decreaseMemoryUsage(pixmapData->memoryUsage(), true); } void QRuntimeGraphicsSystem::removeWindowSurface(QRuntimeWindowSurface *windowSurface) const { int index = m_windowSurfaces.lastIndexOf(windowSurface); m_windowSurfaces.removeAt(index); - decreaseMemoryUsage(windowSurface->memoryUsage(), true); -} - -void QRuntimeGraphicsSystem::increaseMemoryUsage(uint amount) const -{ - m_memoryUsage += amount; - - if (m_graphicsSystemChangeMemoryLimit && - m_memoryUsage < m_graphicsSystemChangeMemoryLimit) { - - QRuntimeGraphicsSystem *gs = const_cast<QRuntimeGraphicsSystem*>(this); - QDeferredGraphicsSystemChange *deferredChange = - new QDeferredGraphicsSystemChange(gs, m_pendingGraphicsSystemName); - deferredChange->launch(); - } -} - -void QRuntimeGraphicsSystem::decreaseMemoryUsage(uint amount, bool persistent) const -{ - m_memoryUsage -= amount; - - if (persistent && m_graphicsSystemChangeMemoryLimit && - m_memoryUsage < m_graphicsSystemChangeMemoryLimit) { - - QRuntimeGraphicsSystem *gs = const_cast<QRuntimeGraphicsSystem*>(this); - QDeferredGraphicsSystemChange *deferredChange = - new QDeferredGraphicsSystemChange(gs, m_pendingGraphicsSystemName); - deferredChange->launch(); - } } #include "qgraphicssystem_runtime.moc" diff --git a/src/gui/painting/qgraphicssystem_runtime_p.h b/src/gui/painting/qgraphicssystem_runtime_p.h index 7aab89c..0232241 100644 --- a/src/gui/painting/qgraphicssystem_runtime_p.h +++ b/src/gui/painting/qgraphicssystem_runtime_p.h @@ -104,8 +104,6 @@ public: virtual QPixmapData *runtimeData() const; - virtual uint memoryUsage() const; - private: const QRuntimeGraphicsSystem *m_graphicsSystem; @@ -131,10 +129,8 @@ public: virtual QPoint offset(const QWidget *widget) const; - virtual uint memoryUsage() const; - - QWindowSurface *m_windowSurface; - QWindowSurface *m_pendingWindowSurface; + QScopedPointer<QWindowSurface> m_windowSurface; + QScopedPointer<QWindowSurface> m_pendingWindowSurface; private: const QRuntimeGraphicsSystem *m_graphicsSystem; @@ -159,7 +155,6 @@ public: void removePixmapData(QRuntimePixmapData *pixmapData) const; void removeWindowSurface(QRuntimeWindowSurface *windowSurface) const; - void setGraphicsSystem(const QString &name, uint memoryUsageLimit); void setGraphicsSystem(const QString &name); QString graphicsSystemName() const { return m_graphicsSystemName; } @@ -170,22 +165,14 @@ public: int windowSurfaceDestroyPolicy() const { return m_windowSurfaceDestroyPolicy; } - uint memoryUsage() const { return m_memoryUsage; } - -private: - - void increaseMemoryUsage(uint amount) const; - void decreaseMemoryUsage(uint amount, bool persistent = false) const; private: - mutable uint m_memoryUsage; int m_windowSurfaceDestroyPolicy; QGraphicsSystem *m_graphicsSystem; mutable QList<QRuntimePixmapData *> m_pixmapDatas; mutable QList<QRuntimeWindowSurface *> m_windowSurfaces; QString m_graphicsSystemName; - uint m_graphicsSystemChangeMemoryLimit; QString m_pendingGraphicsSystemName; friend class QRuntimePixmapData; diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 910b2df..e521e01 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -696,11 +696,10 @@ void QX11PaintEngine::drawLines(const QLine *lines, int lineCount) linef = d->matrix.map(QLineF(lines[i])); } if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - + int x1 = qFloor(linef.x1() + aliasedCoordinateDelta); + int y1 = qFloor(linef.y1() + aliasedCoordinateDelta); + int x2 = qFloor(linef.x2() + aliasedCoordinateDelta); + int y2 = qFloor(linef.y2() + aliasedCoordinateDelta); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } } @@ -730,11 +729,10 @@ void QX11PaintEngine::drawLines(const QLineF *lines, int lineCount) for (int i = 0; i < lineCount; ++i) { QLineF linef = d->matrix.map(lines[i]); if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); - + int x1 = qFloor(linef.x1() + aliasedCoordinateDelta); + int y1 = qFloor(linef.y1() + aliasedCoordinateDelta); + int x2 = qFloor(linef.x2() + aliasedCoordinateDelta); + int y2 = qFloor(linef.y2() + aliasedCoordinateDelta); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } } @@ -1690,8 +1688,8 @@ void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int if (clippedCount > 0) { QVarLengthArray<XPoint> xpoints(clippedCount); for (int i = 0; i < clippedCount; ++i) { - xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta); - xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta); + xpoints[i].x = qFloor(clippedPoints[i].x + aliasedCoordinateDelta); + xpoints[i].y = qFloor(clippedPoints[i].y + aliasedCoordinateDelta); } uint numberPoints = qMin(clippedCount, xlibMaxLinePoints); XPoint *pts = xpoints.data(); diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index e0746fb..881bd6e 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -831,7 +831,7 @@ void QPaintEngineEx::drawEllipse(const QRectF &r) int point_count = 0; x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count); - QVectorPath vp((qreal *) pts, 13, qpaintengineex_ellipse_types, QVectorPath::EllipseHint); + QVectorPath vp((qreal *) pts, point_count, qpaintengineex_ellipse_types, QVectorPath::EllipseHint); draw(vp); } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index c4de7f0..314f349 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -88,14 +88,19 @@ bool qt_show_painter_debug_output = true; extern QPixmap qt_pixmapForBrush(int style, bool invert); -static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, QFontEngine *fe, - QTextCharFormat::UnderlineStyle underlineStyle, - QTextItemInt::RenderFlags flags, qreal width, - const QTextCharFormat &charFormat); void qt_format_text(const QFont &font, const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect, int tabstops, int* tabarray, int tabarraylen, QPainter *painter); +static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, + QTextCharFormat::UnderlineStyle underlineStyle, + QTextItem::RenderFlags flags, qreal width, + const QTextCharFormat &charFormat); +// Helper function to calculate left most position, width and flags for decoration drawing +static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, + const QFixedPoint *positions, int glyphCount, + QFontEngine *fontEngine, const QFont &font, + const QTextCharFormat &charFormat); static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush) { @@ -6051,6 +6056,10 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText currentColor = item->color; } d->extended->drawStaticTextItem(item); + + drawDecorationForGlyphs(this, item->glyphs, item->glyphPositions, + item->numGlyphs, item->fontEngine, staticText_d->font, + QTextCharFormat()); } if (currentColor != oldPen.color()) setPen(oldPen); @@ -6418,9 +6427,9 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) return pixmap; } -static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, QFontEngine *fe, +static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, QTextCharFormat::UnderlineStyle underlineStyle, - QTextItemInt::RenderFlags flags, qreal width, + QTextItem::RenderFlags flags, qreal width, const QTextCharFormat &charFormat) { if (underlineStyle == QTextCharFormat::NoUnderline @@ -6494,6 +6503,50 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, QFontE painter->setBrush(oldBrush); } +static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, + const QFixedPoint *positions, int glyphCount, + QFontEngine *fontEngine, const QFont &font, + const QTextCharFormat &charFormat) +{ + if (!(font.underline() || font.strikeOut() || font.overline())) + return; + + QFixed leftMost; + QFixed rightMost; + QFixed baseLine; + for (int i=0; i<glyphCount; ++i) { + glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]); + if (i == 0 || leftMost > positions[i].x) + leftMost = positions[i].x; + + // We don't support glyphs that do not share a common baseline. If this turns out to + // be a relevant use case, then we need to find clusters of glyphs that share a baseline + // and do a drawTextItemDecorations call per cluster. + if (i == 0 || baseLine < positions[i].y) + baseLine = positions[i].y; + + // We use the advance rather than the actual bounds to match the algorithm in drawText() + if (i == 0 || rightMost < positions[i].x + gm.xoff) + rightMost = positions[i].x + gm.xoff; + } + + QFixed width = rightMost - leftMost; + QTextItem::RenderFlags flags = 0; + + if (font.underline()) + flags |= QTextItem::Underline; + if (font.overline()) + flags |= QTextItem::Overline; + if (font.strikeOut()) + flags |= QTextItem::StrikeOut; + + drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()), + fontEngine, + font.underline() ? QTextCharFormat::SingleUnderline + : QTextCharFormat::NoUnderline, flags, + width.toReal(), charFormat); +} + void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) { #ifdef QT_DEBUG_DRAW diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index 477bd93..8bac1f5 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -67,10 +67,14 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget) TDisplayMode mode = S60->screenDevice()->DisplayMode(); bool isOpaque = qt_widget_private(widget)->isOpaque; - if (mode == EColor16MA && isOpaque) - mode = EColor16MU; // Faster since 16MU -> 16MA is typically accelerated - else if (mode == EColor16MU && !isOpaque) - mode = EColor16MA; // Try for transparency anyway + if (isOpaque) { + mode = EColor16MU; + } else { + if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_3) + mode = Q_SYMBIAN_ECOLOR16MAP; // Symbian^3 WServ has support for ARGB32_PRE + else + mode = EColor16MA; // Symbian prior to Symbian^3 sw accelerates EColor16MA + } // We create empty CFbsBitmap here -> it will be resized in setGeometry CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new |