Merge memrotate and blit feasability checks
Besides reducing duplicate code, this also improves the checks by sharing optimized checks: 1. Fast memrotate will now also trigger with compatible formats (RGB32 over ARGB32) 2. Fast blitting will now also trigger with smooth transforms enabled, if the coordinates are pixel aligned. Change-Id: I576ebb34646d62ed472b1e1772e1b876b8121634 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
2737b5e36a
commit
21ba294345
@ -2214,7 +2214,7 @@ void QRasterPaintEngine::drawImage(const QPointF &p, const QImage &img)
|
|||||||
const QClipData *clip = d->clip();
|
const QClipData *clip = d->clip();
|
||||||
QPointF pt(p.x() + s->matrix.dx(), p.y() + s->matrix.dy());
|
QPointF pt(p.x() + s->matrix.dx(), p.y() + s->matrix.dy());
|
||||||
|
|
||||||
if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img)) {
|
if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img, pt, img.rect())) {
|
||||||
if (!clip) {
|
if (!clip) {
|
||||||
d->blitImage(pt, img, d->deviceRect);
|
d->blitImage(pt, img, d->deviceRect);
|
||||||
return;
|
return;
|
||||||
@ -2285,7 +2285,12 @@ namespace {
|
|||||||
return NoRotation;
|
return NoRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isPixelAligned(const QRectF &rect) {
|
inline bool isPixelAligned(const QPointF &pt)
|
||||||
|
{
|
||||||
|
return QPointF(pt.toPoint()) == pt;
|
||||||
|
}
|
||||||
|
inline bool isPixelAligned(const QRectF &rect)
|
||||||
|
{
|
||||||
return QRectF(rect.toRect()) == rect;
|
return QRectF(rect.toRect()) == rect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2353,17 +2358,12 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
|
|||||||
|
|
||||||
const QClipData *clip = d->clip();
|
const QClipData *clip = d->clip();
|
||||||
|
|
||||||
if (s->matrix.type() > QTransform::TxTranslate
|
if (s->matrix.type() == QTransform::TxRotate
|
||||||
&& !stretch_sr
|
&& !stretch_sr
|
||||||
&& (!clip || clip->hasRectClip)
|
&& (!clip || clip->hasRectClip)
|
||||||
&& s->intOpacity == 256
|
&& s->intOpacity == 256
|
||||||
&& (d->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver
|
&& (d->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver
|
||||||
|| d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)
|
|| d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source))
|
||||||
&& d->rasterBuffer->format == img.format()
|
|
||||||
&& (d->rasterBuffer->format == QImage::Format_RGB16
|
|
||||||
|| d->rasterBuffer->format == QImage::Format_RGB32
|
|
||||||
|| (d->rasterBuffer->format == QImage::Format_ARGB32_Premultiplied
|
|
||||||
&& d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)))
|
|
||||||
{
|
{
|
||||||
RotationType rotationType = qRotationType(s->matrix);
|
RotationType rotationType = qRotationType(s->matrix);
|
||||||
const QPixelLayout::BPP plBpp = qPixelLayouts[d->rasterBuffer->format].bpp;
|
const QPixelLayout::BPP plBpp = qPixelLayouts[d->rasterBuffer->format].bpp;
|
||||||
@ -2371,9 +2371,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
|
|||||||
if (rotationType != NoRotation && qMemRotateFunctions[plBpp][rotationType] && img.rect().contains(sr.toAlignedRect())) {
|
if (rotationType != NoRotation && qMemRotateFunctions[plBpp][rotationType] && img.rect().contains(sr.toAlignedRect())) {
|
||||||
QRectF transformedTargetRect = s->matrix.mapRect(r);
|
QRectF transformedTargetRect = s->matrix.mapRect(r);
|
||||||
|
|
||||||
if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing))
|
if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img, transformedTargetRect.topRight(), sr)) {
|
||||||
|| (isPixelAligned(transformedTargetRect) && isPixelAligned(sr)))
|
|
||||||
{
|
|
||||||
QRect clippedTransformedTargetRect = transformedTargetRect.toRect().intersected(clip ? clip->clipRect : d->deviceRect);
|
QRect clippedTransformedTargetRect = transformedTargetRect.toRect().intersected(clip ? clip->clipRect : d->deviceRect);
|
||||||
if (clippedTransformedTargetRect.isNull())
|
if (clippedTransformedTargetRect.isNull())
|
||||||
return;
|
return;
|
||||||
@ -2507,8 +2505,8 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
|
|||||||
fillPath(path, &d->image_filler_xform);
|
fillPath(path, &d->image_filler_xform);
|
||||||
s->matrix = m;
|
s->matrix = m;
|
||||||
} else {
|
} else {
|
||||||
if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img)) {
|
QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy());
|
||||||
QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy());
|
if (d->canUseImageBlitting(d->rasterBuffer->compositionMode, img, pt, sr)) {
|
||||||
if (!clip) {
|
if (!clip) {
|
||||||
d->blitImage(pt, img, d->deviceRect, sr.toRect());
|
d->blitImage(pt, img, d->deviceRect, sr.toRect());
|
||||||
return;
|
return;
|
||||||
@ -2519,7 +2517,6 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
|
|||||||
} else if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) {
|
} else if (d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) {
|
||||||
SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];
|
SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];
|
||||||
if (func) {
|
if (func) {
|
||||||
QPointF pt(r.x() + s->matrix.dx(), r.y() + s->matrix.dy());
|
|
||||||
if (!clip) {
|
if (!clip) {
|
||||||
d->drawImage(pt, img, func, d->deviceRect, s->intOpacity, sr.toRect());
|
d->drawImage(pt, img, func, d->deviceRect, s->intOpacity, sr.toRect());
|
||||||
return;
|
return;
|
||||||
@ -3754,12 +3751,22 @@ bool QRasterPaintEnginePrivate::canUseFastImageBlending(QPainter::CompositionMod
|
|||||||
&& !image.hasAlphaChannel()));
|
&& !image.hasAlphaChannel()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QRasterPaintEnginePrivate::canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image) const
|
bool QRasterPaintEnginePrivate::canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image, const QPointF &pt, const QRectF &sr) const
|
||||||
{
|
{
|
||||||
Q_Q(const QRasterPaintEngine);
|
Q_Q(const QRasterPaintEngine);
|
||||||
const QRasterPaintEngineState *s = q->state();
|
|
||||||
|
|
||||||
if (!s->flags.fast_images || s->intOpacity != 256 || qt_depthForFormat(rasterBuffer->format) < 8)
|
if (!(mode == QPainter::CompositionMode_Source
|
||||||
|
|| (mode == QPainter::CompositionMode_SourceOver
|
||||||
|
&& !image.hasAlphaChannel())))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QRasterPaintEngineState *s = q->state();
|
||||||
|
Q_ASSERT(s->matrix.type() <= QTransform::TxTranslate || s->matrix.type() == QTransform::TxRotate);
|
||||||
|
|
||||||
|
if (s->intOpacity != 256
|
||||||
|
|| image.depth() < 8
|
||||||
|
|| ((s->renderHints & (QPainter::SmoothPixmapTransform | QPainter::Antialiasing))
|
||||||
|
&& (!isPixelAligned(pt) || !isPixelAligned(sr))))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QImage::Format dFormat = rasterBuffer->format;
|
QImage::Format dFormat = rasterBuffer->format;
|
||||||
@ -3767,18 +3774,13 @@ bool QRasterPaintEnginePrivate::canUseImageBlitting(QPainter::CompositionMode mo
|
|||||||
// Formats must match or source format must be a subset of destination format
|
// Formats must match or source format must be a subset of destination format
|
||||||
if (dFormat != sFormat && image.pixelFormat().alphaUsage() == QPixelFormat::IgnoresAlpha) {
|
if (dFormat != sFormat && image.pixelFormat().alphaUsage() == QPixelFormat::IgnoresAlpha) {
|
||||||
if ((sFormat == QImage::Format_RGB32 && dFormat == QImage::Format_ARGB32)
|
if ((sFormat == QImage::Format_RGB32 && dFormat == QImage::Format_ARGB32)
|
||||||
|| (sFormat == QImage::Format_RGBX8888 && dFormat == QImage::Format_RGBA8888))
|
|| (sFormat == QImage::Format_RGBX8888 && dFormat == QImage::Format_RGBA8888)
|
||||||
|
|| (sFormat == QImage::Format_RGBX64 && dFormat == QImage::Format_RGBA64))
|
||||||
sFormat = dFormat;
|
sFormat = dFormat;
|
||||||
else
|
else
|
||||||
sFormat = qt_maybeAlphaVersionWithSameDepth(sFormat); // this returns premul formats
|
sFormat = qt_maybeAlphaVersionWithSameDepth(sFormat); // this returns premul formats
|
||||||
}
|
}
|
||||||
if (dFormat != sFormat)
|
return (dFormat == sFormat);
|
||||||
return false;
|
|
||||||
|
|
||||||
return s->matrix.type() <= QTransform::TxTranslate
|
|
||||||
&& (mode == QPainter::CompositionMode_Source
|
|
||||||
|| (mode == QPainter::CompositionMode_SourceOver
|
|
||||||
&& !image.hasAlphaChannel()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color)
|
QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color)
|
||||||
|
@ -306,7 +306,7 @@ public:
|
|||||||
|
|
||||||
void recalculateFastImages();
|
void recalculateFastImages();
|
||||||
bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
|
bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
|
||||||
bool canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image) const;
|
bool canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image, const QPointF &pt, const QRectF &sr) const;
|
||||||
|
|
||||||
QPaintDevice *device;
|
QPaintDevice *device;
|
||||||
QScopedPointer<QOutlineMapper> outlineMapper;
|
QScopedPointer<QOutlineMapper> outlineMapper;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user