diff options
-rwxr-xr-x | bin/createpackage.pl | 24 | ||||
-rwxr-xr-x | bin/patch_capabilities.pl | 26 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_symbian.cpp | 38 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_symbian_p.h | 8 | ||||
-rw-r--r-- | src/gui/painting/qrasterizer.cpp | 180 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 33 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 3 | ||||
-rw-r--r-- | src/openvg/qpaintengine_vg.cpp | 7 | ||||
-rw-r--r-- | tests/auto/qapplication/test/test.pro | 2 | ||||
-rw-r--r-- | tests/auto/qpainter/tst_qpainter.cpp | 23 | ||||
-rw-r--r-- | tests/auto/qtimer/tst_qtimer.cpp | 27 |
11 files changed, 223 insertions, 148 deletions
diff --git a/bin/createpackage.pl b/bin/createpackage.pl index cce0b54..85be5d3 100755 --- a/bin/createpackage.pl +++ b/bin/createpackage.pl @@ -212,21 +212,21 @@ my $certpath = File::Spec->catdir($scriptpath, File::Spec->updir(), "src/s60inst # Check some pre-conditions and print error messages if needed. unless (length($templatepkg)) { - print "\nError: Template PKG filename is not defined!\n"; + print "\nERROR: Template PKG filename is not defined!\n"; Usage(); } # Check template exist stat($templatepkg); unless( -e _ ) { - print "\nError: Package description file '$templatepkg' does not exist!\n"; + print "\nERROR: Package description file '$templatepkg' does not exist!\n"; Usage(); } # Check certifcate preconditions and set default certificate variables if needed if (length($certificate)) { unless(length($key)) { - print "\nError: Custom certificate key file parameter missing.!\n"; + print "\nERROR: Custom certificate key file parameter missing.!\n"; Usage(); } } else { @@ -261,7 +261,7 @@ if (length($certfile)) { # Do some validation unless(scalar(@certinfo) >= 2 && scalar(@certinfo) <= 3 && length($certinfo[0]) && length($certinfo[1]) ) { - print "\nError: $certfile line '$_' does not contain valid information!\n"; + print "\nERROR: $certfile line '$_' does not contain valid information!\n"; Usage(); } @@ -280,14 +280,14 @@ if (!$preservePkgOutput) { local $/; # read template file -open( TEMPLATE, $templatepkg) or die "Error '$templatepkg': $!\n"; +open( TEMPLATE, $templatepkg) or die "ERROR: '$templatepkg': $!"; $_=<TEMPLATE>; close (TEMPLATE); # If the pkg file does not contain macros, there is no need for platform or target. if (m/\$\(PLATFORM\)/) { unless (length($platform) && length($target)) { - print "\nError: Platform or target is not defined!\n"; + print "\nERROR: Platform or target is not defined!\n"; Usage(); } } @@ -297,7 +297,7 @@ s/\$\(PLATFORM\)/$platform/gm; s/\$\(TARGET\)/$target/gm; #write the output -open( OUTPUT, ">$pkgoutput" ) or die "Error '$pkgoutput' $!\n"; +open( OUTPUT, ">$pkgoutput" ) or die "ERROR: '$pkgoutput' $!"; print OUTPUT $_; close OUTPUT; @@ -306,7 +306,7 @@ if ($preprocessonly) { } if($stub) { - if(!($epocroot)) { die("EPOCROOT must be set to create stub sis files"); } + if(!($epocroot)) { die("ERROR: EPOCROOT must be set to create stub sis files"); } my $systeminstall = "$epocroot/epoc32/data/z/system/install"; mkpath($systeminstall); my $stub_sis_name = $systeminstall."/".$stub_sis_name; @@ -319,15 +319,15 @@ if($stub) { && !$onlyUnsigned) { print("Auto-patching capabilities for self signed package.\n"); my $patch_capabilities = File::Spec->catfile(dirname($0), "patch_capabilities"); - system ("$patch_capabilities $pkgoutput"); + system ("$patch_capabilities $pkgoutput") and die ("ERROR: Automatic patching failed"); } # Create SIS. # The 'and' is because system uses 0 to indicate success. if($epocroot) { - system ("$epocroot/epoc32/tools/makesis $pkgoutput $unsigned_sis_name") and die ("makesis failed"); + system ("$epocroot/epoc32/tools/makesis $pkgoutput $unsigned_sis_name") and die ("ERROR: makesis failed"); } else { - system ("makesis $pkgoutput $unsigned_sis_name") and die ("makesis failed"); + system ("makesis $pkgoutput $unsigned_sis_name") and die ("ERROR: makesis failed"); } print("\n"); @@ -354,7 +354,7 @@ if($stub) { my $relcert = File::Spec->abs2rel($certificate); my $relkey = File::Spec->abs2rel($key); # The 'and' is because system uses 0 to indicate success. - system ("signsis $unsigned_sis_name $signed_sis_name $relcert $relkey $passphrase") and die ("signsis failed"); + system ("signsis $unsigned_sis_name $signed_sis_name $relcert $relkey $passphrase") and die ("ERROR: signsis failed"); # Check if creating signed SIS Succeeded stat($signed_sis_name); diff --git a/bin/patch_capabilities.pl b/bin/patch_capabilities.pl index a85f073..06ab116 100755 --- a/bin/patch_capabilities.pl +++ b/bin/patch_capabilities.pl @@ -152,7 +152,7 @@ if (@ARGV) my $newLine = $line; # Patch pkg UID if it's in protected range - if ($line =~ m/^\#.*\((0x[0-7][0-9|a-f|A-F]*)\).*$/) + if ($line =~ m/^\#.*\((0x[0-7][0-9a-fA-F]*)\).*$/) { my $oldUID = $1; my $newUID = $oldUID; @@ -162,7 +162,7 @@ if (@ARGV) } # Patch embedded sis name and UID if UID is in protected range - if ($line =~ m/^@\"*(.*\.sis).*\((0x[0-7][0-9|a-f|A-F]*)\).*$/) + if ($line =~ m/^@\"*(.*\.sis).*\((0x[0-7][0-9a-fA-F]*)\).*$/) { my $oldSisName = $1; my $oldUID = $2; @@ -280,7 +280,16 @@ if (@ARGV) my $capabilitiesToAllow = join(" ", @capabilitiesToAllow); my @capabilitiesToDrop; while (<$dllCaps>) { - if (/^Vendor ID: (.*)$/) { + if (/^Secure ID: ([0-7][0-9a-fA-F]*)$/) { + my $exeSid = $1; + if ($binaryBaseName =~ /\.exe$/) { + # Installer refuses to install protected executables in a self signed package, so abort if one is detected. + # We can't simply just patch the executable SID, as any registration resources executable uses will be linked to it via SID. + print ("Patching: Executable with SID in the protected range (0x$exeSid) detected: \"$binaryBaseName\". A self-signed sis with protected executables is not supported.\n"); + exit(1); + } + } + if (/^Vendor ID: ([0-9a-fA-F]*)$/) { $originalVid = "$1"; } if (!$capsFound) { @@ -303,8 +312,15 @@ if (@ARGV) my $capsToDropStr = join("\", \"", @capabilitiesToDrop); $capsToDropStr =~ s/\", \"$//; - print ("Patching: The following capabilities used in \"$binaryBaseName\" are not compatible with a self-signed package and will be removed: \"$capsToDropStr\".\n"); - $executeNeeded = 1; + if ($binaryBaseName =~ /\.exe$/) { + # While libraries often have capabilities they do not themselves need just to enable them to be loaded by wider variety of processes, + # executables are more likely to need every capability they have been assigned or they won't function correctly. + print ("Patching: Executable with capabilities incompatible with self-signing detected: \"$binaryBaseName\". (Incompatible capabilities: \"$capsToDropStr\".) Reducing capabilities is only supported for libraries.\n"); + exit(1); + } else { + print ("Patching: The following capabilities used in \"$binaryBaseName\" are not compatible with a self-signed package and will be removed: \"$capsToDropStr\".\n"); + $executeNeeded = 1; + } } $commandToExecute = sprintf($baseCommandToExecute, join(" ", @capabilitiesToSet)); } diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 5cc6ae3..d8cc344 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -127,9 +127,9 @@ private: * cannot change active objects that we do not own, but the active objects that Qt owns will use * this as a base class with convenience functions. * - * Here is how it works: On every RunL, the deriving class should call okToRun(). This will allow - * exactly one run of the active object, and mark it as such. If it is called again, it will return - * false, and add the object to a queue so it can be run later. + * Here is how it works: On every RunL, the deriving class should call maybeQueueForLater(). + * This will return whether the active object has been queued, or whether it should run immediately. + * Queued objects will run again after other events have been processed. * * The QCompleteDeferredAOs class is a special object that runs after all others, which will * reactivate the objects that were previously not run. @@ -149,7 +149,7 @@ QActiveObject::~QActiveObject() m_dispatcher->removeDeferredActiveObject(this); } -bool QActiveObject::okToRun() +bool QActiveObject::maybeQueueForLater() { Q_ASSERT(!m_hasRunAgain); @@ -157,12 +157,12 @@ bool QActiveObject::okToRun() // First occurrence of this event in this iteration. m_hasAlreadyRun = true; m_iterationCount = m_dispatcher->iterationCount(); - return true; + return false; } else { // The event has already occurred. m_dispatcher->addDeferredActiveObject(this); m_hasRunAgain = true; - return false; + return true; } } @@ -178,8 +178,7 @@ void QActiveObject::reactivateAndComplete() } QWakeUpActiveObject::QWakeUpActiveObject(QEventDispatcherSymbian *dispatcher) - : CActive(WAKE_UP_PRIORITY), - m_dispatcher(dispatcher) + : QActiveObject(WAKE_UP_PRIORITY, dispatcher) { CActiveScheduler::Add(this); iStatus = KRequestPending; @@ -201,6 +200,9 @@ void QWakeUpActiveObject::DoCancel() void QWakeUpActiveObject::RunL() { + if (maybeQueueForLater()) + return; + iStatus = KRequestPending; SetActive(); QT_TRYCATCH_LEAVING(m_dispatcher->wakeUpWasCalled()); @@ -270,7 +272,7 @@ void QTimerActiveObject::Run() return; } - if (!okToRun()) + if (maybeQueueForLater()) return; if (m_timerInfo->interval > 0) { @@ -630,7 +632,7 @@ void QSocketActiveObject::DoCancel() void QSocketActiveObject::RunL() { - if (!okToRun()) + if (maybeQueueForLater()) return; QT_TRYCATCH_LEAVING(m_dispatcher->socketFired(this)); @@ -722,6 +724,7 @@ QEventDispatcherSymbian::QEventDispatcherSymbian(QObject *parent) m_interrupt(false), m_wakeUpDone(0), m_iterationCount(0), + m_insideTimerEvent(false), m_noSocketEvents(false) { #ifdef QT_SYMBIAN_PRIORITY_DROP @@ -772,6 +775,9 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla { bool handledAnyEvent = false; bool oldNoSocketEventsValue = m_noSocketEvents; + bool oldInsideTimerEventValue = m_insideTimerEvent; + + m_insideTimerEvent = false; QT_TRY { Q_D(QAbstractEventDispatcher); @@ -862,6 +868,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla } m_noSocketEvents = oldNoSocketEventsValue; + m_insideTimerEvent = oldInsideTimerEventValue; return handledAnyEvent; } @@ -882,10 +889,13 @@ void QEventDispatcherSymbian::timerFired(int timerId) } timerInfo->inTimerEvent = true; + bool oldInsideTimerEventValue = m_insideTimerEvent; + m_insideTimerEvent = true; QTimerEvent event(timerInfo->timerId); QCoreApplication::sendEvent(timerInfo->receiver, &event); + m_insideTimerEvent = oldInsideTimerEventValue; timerInfo->inTimerEvent = false; return; @@ -1052,6 +1062,14 @@ void QEventDispatcherSymbian::registerTimer ( int timerId, int interval, QObject m_timerList.insert(timerId, timer); timer->timerAO->Start(); + + if (m_insideTimerEvent) + // If we are inside a timer event, we need to prevent event starvation + // by preventing newly created timers from running in the same event processing + // iteration. Do this by calling the maybeQueueForLater() function to "fake" that we have + // already run once. This will cause the next run to be added to the deferred + // queue instead. + timer->timerAO->maybeQueueForLater(); } bool QEventDispatcherSymbian::unregisterTimer ( int timerId ) diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h index bc42753..1486db5 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian_p.h +++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h @@ -82,7 +82,7 @@ public: QActiveObject(TInt priority, QEventDispatcherSymbian *dispatcher); ~QActiveObject(); - bool okToRun(); + bool maybeQueueForLater(); void reactivateAndComplete(); @@ -95,7 +95,7 @@ private: int m_iterationCount; }; -class QWakeUpActiveObject : public CActive +class QWakeUpActiveObject : public QActiveObject { public: QWakeUpActiveObject(QEventDispatcherSymbian *dispatcher); @@ -106,9 +106,6 @@ public: protected: void DoCancel(); void RunL(); - -private: - QEventDispatcherSymbian *m_dispatcher; }; struct SymbianTimerInfo : public QSharedData @@ -277,6 +274,7 @@ private: QAtomicInt m_wakeUpDone; unsigned char m_iterationCount; + bool m_insideTimerEvent; bool m_noSocketEvents; QList<QSocketActiveObject *> m_deferredSocketEvents; diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index f8f8afb..4fded1f 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -65,6 +65,12 @@ typedef int Q16Dot16; #define COORD_ROUNDING 1 // 0: round up, 1: round down #define COORD_OFFSET 32 // 26.6, 32 is half a pixel +static inline QT_FT_Vector PointToVector(const QPointF &p) +{ + QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) }; + return result; +} + class QSpanBuffer { public: QSpanBuffer(ProcessSpans blend, void *data, const QRect &clipRect) @@ -693,9 +699,9 @@ static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 } } -static inline bool q16Dot16Compare(qreal p1, qreal p2) +static inline bool q26Dot6Compare(qreal p1, qreal p2) { - return FloatToQ16Dot16(p2 - p1) == 0; + return int((p2 - p1) * 64.) == 0; } static inline qreal qFloorF(qreal v) @@ -708,6 +714,12 @@ static inline qreal qFloorF(qreal v) return floor(v); } +static inline QPointF snapTo26Dot6Grid(const QPointF &p) +{ + return QPointF(qFloorF(p.x() * 64) * (1 / qreal(64)), + qFloorF(p.y() * 64) * (1 / qreal(64))); +} + void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap) { if (a == b || width == 0 || d->clipRect.isEmpty()) @@ -718,17 +730,21 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, QPointF pa = a; QPointF pb = b; - QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5; - if (squareCap) - offs += QPointF(offs.y(), offs.x()); + if (squareCap) { + QPointF delta = pb - pa; + pa -= (0.5f * width) * delta; + pb += (0.5f * width) * delta; + } + + QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5; const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs); - if (!clip.contains(a) || !clip.contains(b)) { + if (!clip.contains(pa) || !clip.contains(pb)) { qreal t1 = 0; qreal t2 = 1; - const qreal o[2] = { a.x(), a.y() }; - const qreal d[2] = { b.x() - a.x(), b.y() - a.y() }; + const qreal o[2] = { pa.x(), pa.y() }; + const qreal d[2] = { pb.x() - pa.x(), pb.y() - pa.y() }; const qreal low[2] = { clip.left(), clip.top() }; const qreal high[2] = { clip.right(), clip.bottom() }; @@ -751,8 +767,12 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (t1 >= t2) return; } - pa = a + (b - a) * t1; - pb = a + (b - a) * t2; + + QPointF npa = pa + (pb - pa) * t1; + QPointF npb = pa + (pb - pa) * t2; + + pa = npa; + pb = npb; } if (!d->antialiased) { @@ -763,15 +783,6 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, } { - const qreal gridResolution = 64; - const qreal reciprocal = 1 / gridResolution; - - // snap to grid to prevent large slopes - pa.rx() = qFloorF(pa.rx() * gridResolution) * reciprocal; - pa.ry() = qFloorF(pa.ry() * gridResolution) * reciprocal; - pb.rx() = qFloorF(pb.rx() * gridResolution) * reciprocal; - pb.ry() = qFloorF(pb.ry() * gridResolution) * reciprocal; - // old delta const QPointF d0 = a - b; const qreal w0 = d0.x() * d0.x() + d0.y() * d0.y(); @@ -789,7 +800,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, QSpanBuffer buffer(d->blend, d->data, d->clipRect); - if (q16Dot16Compare(pa.y(), pb.y())) { + if (q26Dot6Compare(pa.y(), pb.y())) { const qreal x = (pa.x() + pb.x()) * 0.5f; const qreal dx = qAbs(pb.x() - pa.x()) * 0.5f; @@ -799,26 +810,16 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, pa = QPointF(x, y - dy); pb = QPointF(x, y + dy); - if (squareCap) - width = 1 / width + 1.0f; - else - width = 1 / width; - - squareCap = false; + width = 1 / width; } - if (q16Dot16Compare(pa.x(), pb.x())) { + if (q26Dot6Compare(pa.x(), pb.x())) { if (pa.y() > pb.y()) qSwap(pa, pb); const qreal dy = pb.y() - pa.y(); const qreal halfWidth = 0.5f * width * dy; - if (squareCap) { - pa.ry() -= halfWidth; - pb.ry() += halfWidth; - } - qreal left = pa.x() - halfWidth; qreal right = pa.x() + halfWidth; @@ -828,7 +829,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, pa.ry() = qBound(qreal(d->clipRect.top()), pa.y(), qreal(d->clipRect.bottom() + 1)); pb.ry() = qBound(qreal(d->clipRect.top()), pb.y(), qreal(d->clipRect.bottom() + 1)); - if (q16Dot16Compare(left, right) || q16Dot16Compare(pa.y(), pb.y())) + if (q26Dot6Compare(left, right) || q26Dot6Compare(pa.y(), pb.y())) return; if (d->antialiased) { @@ -899,11 +900,6 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, delta *= 0.5f * width; const QPointF perp(delta.y(), -delta.x()); - if (squareCap) { - pa -= delta; - pb += delta; - } - QPointF top; QPointF left; QPointF right; @@ -921,14 +917,36 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bottom = pb + perp; } + top = snapTo26Dot6Grid(top); + bottom = snapTo26Dot6Grid(bottom); + left = snapTo26Dot6Grid(left); + right = snapTo26Dot6Grid(right); + const qreal topBound = qBound(qreal(d->clipRect.top()), top.y(), qreal(d->clipRect.bottom())); const qreal bottomBound = qBound(qreal(d->clipRect.top()), bottom.y(), qreal(d->clipRect.bottom())); - const qreal leftSlope = (left.x() - top.x()) / (left.y() - top.y()); - const qreal rightSlope = -1.0f / leftSlope; + const QPointF topLeftEdge = left - top; + const QPointF topRightEdge = right - top; + const QPointF bottomLeftEdge = bottom - left; + const QPointF bottomRightEdge = bottom - right; + + const qreal topLeftSlope = topLeftEdge.x() / topLeftEdge.y(); + const qreal bottomLeftSlope = bottomLeftEdge.x() / bottomLeftEdge.y(); + + const qreal topRightSlope = topRightEdge.x() / topRightEdge.y(); + const qreal bottomRightSlope = bottomRightEdge.x() / bottomRightEdge.y(); + + const Q16Dot16 topLeftSlopeFP = FloatToQ16Dot16(topLeftSlope); + const Q16Dot16 topRightSlopeFP = FloatToQ16Dot16(topRightSlope); - const Q16Dot16 leftSlopeFP = FloatToQ16Dot16(leftSlope); - const Q16Dot16 rightSlopeFP = FloatToQ16Dot16(rightSlope); + const Q16Dot16 bottomLeftSlopeFP = FloatToQ16Dot16(bottomLeftSlope); + const Q16Dot16 bottomRightSlopeFP = FloatToQ16Dot16(bottomRightSlope); + + const Q16Dot16 invTopLeftSlopeFP = FloatToQ16Dot16(1 / topLeftSlope); + const Q16Dot16 invTopRightSlopeFP = FloatToQ16Dot16(1 / topRightSlope); + + const Q16Dot16 invBottomLeftSlopeFP = FloatToQ16Dot16(1 / bottomLeftSlope); + const Q16Dot16 invBottomRightSlopeFP = FloatToQ16Dot16(1 / bottomRightSlope); if (d->antialiased) { const Q16Dot16 iTopFP = IntToQ16Dot16(int(topBound)); @@ -936,16 +954,16 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, const Q16Dot16 iRightFP = IntToQ16Dot16(int(right.y())); const Q16Dot16 iBottomFP = IntToQ16Dot16(int(bottomBound)); - Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * leftSlope); - Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * rightSlope); + Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topLeftSlope); + Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topRightSlope); Q16Dot16 leftIntersectBf = 0; Q16Dot16 rightIntersectBf = 0; if (iLeftFP < iTopFP) - leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * rightSlope); + leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope); if (iRightFP < iTopFP) - rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * leftSlope); + rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope); Q16Dot16 rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom; Q16Dot16 topLeftIntersectAf, topLeftIntersectBf, topRightIntersectAf, topRightIntersectBf; @@ -960,9 +978,9 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, rowTop = qMax(iTopFP, yTopFP); topLeftIntersectAf = leftIntersectAf + - Q16Dot16Multiply(leftSlopeFP, rowTop - iTopFP); + Q16Dot16Multiply(topLeftSlopeFP, rowTop - iTopFP); topRightIntersectAf = rightIntersectAf + - Q16Dot16Multiply(rightSlopeFP, rowTop - iTopFP); + Q16Dot16Multiply(topRightSlopeFP, rowTop - iTopFP); Q16Dot16 yFP = iTopFP; while (yFP <= iBottomFP) { @@ -974,30 +992,30 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (yFP == iLeftFP) { const int y = Q16Dot16ToInt(yFP); - leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * rightSlope); - topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(rightSlopeFP, rowTopLeft - yFP); - bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(leftSlopeFP, rowBottomLeft - yFP); + leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope); + topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowTopLeft - yFP); + bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(topLeftSlopeFP, rowBottomLeft - yFP); } else { topLeftIntersectBf = leftIntersectBf; - bottomLeftIntersectAf = leftIntersectAf + leftSlopeFP; + bottomLeftIntersectAf = leftIntersectAf + topLeftSlopeFP; } if (yFP == iRightFP) { const int y = Q16Dot16ToInt(yFP); - rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * leftSlope); - topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(leftSlopeFP, rowTopRight - yFP); - bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(rightSlopeFP, rowBottomRight - yFP); + rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope); + topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowTopRight - yFP); + bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(topRightSlopeFP, rowBottomRight - yFP); } else { topRightIntersectBf = rightIntersectBf; - bottomRightIntersectAf = rightIntersectAf + rightSlopeFP; + bottomRightIntersectAf = rightIntersectAf + topRightSlopeFP; } if (yFP == iBottomFP) { - bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(rightSlopeFP, rowBottom - yFP); - bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(leftSlopeFP, rowBottom - yFP); + bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowBottom - yFP); + bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowBottom - yFP); } else { - bottomLeftIntersectBf = leftIntersectBf + rightSlopeFP; - bottomRightIntersectBf = rightIntersectBf + leftSlopeFP; + bottomLeftIntersectBf = leftIntersectBf + bottomLeftSlopeFP; + bottomRightIntersectBf = rightIntersectBf + bottomRightSlopeFP; } if (yFP < iLeftFP) { @@ -1042,21 +1060,21 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (yFP <= iLeftFP) excluded += intersectPixelFP(x, rowTop, rowBottomLeft, bottomLeftIntersectAf, topLeftIntersectAf, - leftSlopeFP, -rightSlopeFP); + topLeftSlopeFP, invTopLeftSlopeFP); if (yFP >= iLeftFP) excluded += intersectPixelFP(x, rowTopLeft, rowBottom, topLeftIntersectBf, bottomLeftIntersectBf, - rightSlopeFP, -leftSlopeFP); + bottomLeftSlopeFP, invBottomLeftSlopeFP); if (x >= rightMin) { if (yFP <= iRightFP) excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, - rightSlopeFP, -leftSlopeFP); + topRightSlopeFP, invTopRightSlopeFP); if (yFP >= iRightFP) excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, - leftSlopeFP, -rightSlopeFP); + bottomRightSlopeFP, invBottomRightSlopeFP); } Q16Dot16 coverage = rowHeight - excluded; @@ -1074,11 +1092,11 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (yFP <= iRightFP) excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, - rightSlopeFP, -leftSlopeFP); + topRightSlopeFP, invTopRightSlopeFP); if (yFP >= iRightFP) excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, - leftSlopeFP, -rightSlopeFP); + bottomRightSlopeFP, invBottomRightSlopeFP); Q16Dot16 coverage = rowHeight - excluded; buffer.addSpan(x, 1, Q16Dot16ToInt(yFP), @@ -1086,10 +1104,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, ++x; } - leftIntersectAf += leftSlopeFP; - leftIntersectBf += rightSlopeFP; - rightIntersectAf += rightSlopeFP; - rightIntersectBf += leftSlopeFP; + leftIntersectAf += topLeftSlopeFP; + leftIntersectBf += bottomLeftSlopeFP; + rightIntersectAf += topRightSlopeFP; + rightIntersectBf += bottomRightSlopeFP; topLeftIntersectAf = leftIntersectAf; topRightIntersectAf = rightIntersectAf; @@ -1103,10 +1121,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, int iBottom = bottom.y() < 0.5f? -1 : int(bottom.y() - 0.5f); int iMiddle = qMin(iLeft, iRight); - Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * leftSlope); - Q16Dot16 leftIntersectBf = FloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * rightSlope); - Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * rightSlope); - Q16Dot16 rightIntersectBf = FloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * leftSlope); + Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope); + Q16Dot16 leftIntersectBf = FloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope); + Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope); + Q16Dot16 rightIntersectBf = FloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope); int ny; int y = iTop; @@ -1128,10 +1146,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, ri += rs; \ } - DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, leftSlopeFP, rightSlopeFP) - DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, rightSlopeFP, rightSlopeFP) - DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, leftSlopeFP, leftSlopeFP) - DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, rightSlopeFP, leftSlopeFP) + DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, topLeftSlopeFP, topRightSlopeFP) + DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, bottomLeftSlopeFP, topRightSlopeFP) + DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, topLeftSlopeFP, bottomRightSlopeFP); + DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, bottomLeftSlopeFP, bottomRightSlopeFP); #undef DO_SEGMENT } } @@ -1183,12 +1201,6 @@ void QRasterizer::rasterize(const QT_FT_Outline *outline, Qt::FillRule fillRule) d->scanConverter.end(); } -static inline QT_FT_Vector PointToVector(const QPointF &p) -{ - QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) }; - return result; -} - void QRasterizer::rasterize(const QPainterPath &path, Qt::FillRule fillRule) { if (path.isEmpty()) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 15070d4..0d1a66e 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1689,9 +1689,6 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) workaround_brokenFBOReadBack = false; workaroundsCached = false; - workaround_brokenTextureFromPixmap = false; - workaround_brokenTextureFromPixmap_init = false; - for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) vertexAttributeArraysEnabledState[i] = false; } @@ -2577,34 +2574,18 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, } } -#if defined(Q_WS_X11) - // Try to use texture_from_pixmap +#if defined(Q_WS_X11) && !defined(QT_NO_EGL) + // Only try to use texture_from_pixmap under X11/EGL const QX11Info *xinfo = qt_x11Info(paintDevice); if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType && xinfo && xinfo->screen() == pixmap.x11Info().screen() && target == GL_TEXTURE_2D) { - if (!workaround_brokenTextureFromPixmap_init) { - workaround_brokenTextureFromPixmap_init = true; - - const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION))); - const int pos = versionString.indexOf("NVIDIA "); - - if (pos >= 0) { - const QByteArray nvidiaVersionString = versionString.mid(pos + strlen("NVIDIA ")); - - if (nvidiaVersionString.startsWith("195") || nvidiaVersionString.startsWith("256")) - workaround_brokenTextureFromPixmap = true; - } - } - - if (!workaround_brokenTextureFromPixmap) { - texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options); - if (texture) { - texture->options |= QGLContext::MemoryManagedBindOption; - texture->boundPixmap = pd; - boundPixmaps.insert(pd, QPixmap(pixmap)); - } + texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options); + if (texture) { + texture->options |= QGLContext::MemoryManagedBindOption; + texture->boundPixmap = pd; + boundPixmaps.insert(pd, QPixmap(pixmap)); } } #endif diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 623eeaf..6323ce2 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -401,9 +401,6 @@ public: uint workaround_brokenFBOReadBack : 1; uint workaroundsCached : 1; - uint workaround_brokenTextureFromPixmap : 1; - uint workaround_brokenTextureFromPixmap_init : 1; - QPaintDevice *paintDevice; QColor transpColor; QGLContext *q_ptr; diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 3c2fd3d..74395a2 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -248,7 +248,11 @@ public: inline void ensurePathTransform() { if (!pathTransformSet) { - setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, pathTransform); + QTransform aliasedTransform = pathTransform; + if (renderingQuality == VG_RENDERING_QUALITY_NONANTIALIASED && currentPen != Qt::NoPen) + aliasedTransform = aliasedTransform + * QTransform::fromTranslate(aliasedCoordinateDelta, -aliasedCoordinateDelta); + setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, aliasedTransform); pathTransformSet = true; } } @@ -306,6 +310,7 @@ inline void QVGPaintEnginePrivate::setRenderingQuality(VGRenderingQuality mode) if (renderingQuality != mode) { vgSeti(VG_RENDERING_QUALITY, mode); renderingQuality = mode; + pathTransformSet = false; // need to tweak transform for aliased stroking } } diff --git a/tests/auto/qapplication/test/test.pro b/tests/auto/qapplication/test/test.pro index 30eb751..2c54c37 100644 --- a/tests/auto/qapplication/test/test.pro +++ b/tests/auto/qapplication/test/test.pro @@ -12,7 +12,7 @@ wince* { } symbian: { - additional.sources = ../desktopsettingsaware/desktopsettingsaware.exe + additional.sources = $$OUT_PWD/../desktopsettingsaware/desktopsettingsaware.exe additional.path = desktopsettingsaware someTest.sources = test.pro someTest.path = test diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index f358681..45f5c3e 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -252,6 +252,8 @@ private slots: void QTBUG5939_attachPainterPrivate(); + void drawPointScaled(); + private: void fillData(); void setPenColor(QPainter& p); @@ -3170,7 +3172,6 @@ void fpe_steepSlopes() p.setRenderHint(QPainter::Antialiasing, antialiased); p.setTransform(transform); - QEXPECT_FAIL("steep line 3 aa", "needs to be fixed", Continue); p.drawLine(line); } @@ -4522,6 +4523,26 @@ void tst_QPainter::QTBUG5939_attachPainterPrivate() QCOMPARE(widget->deviceTransform, proxy->deviceTransform); } +void tst_QPainter::drawPointScaled() +{ + QImage image(32, 32, QImage::Format_RGB32); + image.fill(0xffffffff); + + QPainter p(&image); + + p.scale(0.1, 0.1); + + QPen pen; + pen.setWidth(1000); + pen.setColor(Qt::red); + + p.setPen(pen); + p.drawPoint(0, 0); + p.end(); + + QCOMPARE(image.pixel(16, 16), 0xffff0000); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index f23d065..102308e 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -89,6 +89,7 @@ private slots: void recurseOnTimeoutAndStopTimer(); void QTBUG13633_dontBlockEvents(); + void postedEventsShouldNotStarveTimers(); }; class TimerHelper : public QObject @@ -723,5 +724,31 @@ void tst_QTimer::QTBUG13633_dontBlockEvents() QVERIFY(t.total > 2); } +class SlotRepeater : public QObject { + Q_OBJECT +public: + SlotRepeater() {} + +public slots: + void repeatThisSlot() + { + QMetaObject::invokeMethod(this, "repeatThisSlot", Qt::QueuedConnection); + } +}; + +void tst_QTimer::postedEventsShouldNotStarveTimers() +{ + TimerHelper timerHelper; + QTimer timer; + connect(&timer, SIGNAL(timeout()), &timerHelper, SLOT(timeout())); + timer.setInterval(0); + timer.setSingleShot(false); + timer.start(); + SlotRepeater slotRepeater; + slotRepeater.repeatThisSlot(); + QTest::qWait(100); + QVERIFY(timerHelper.count > 5); +} + QTEST_MAIN(tst_QTimer) #include "tst_qtimer.moc" |