diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qgenericpluginfactory.cpp | 8 | ||||
-rw-r--r-- | src/gui/kernel/qinputdevicemanager.cpp | 1 | ||||
-rw-r--r-- | src/gui/kernel/qinputdevicemanager_p.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qopenglwindow.cpp | 245 | ||||
-rw-r--r-- | src/gui/painting/qimagescale.cpp | 160 | ||||
-rw-r--r-- | src/gui/painting/qimagescale_sse4.cpp | 42 | ||||
-rw-r--r-- | src/gui/painting/qplatformbackingstore.cpp | 67 | ||||
-rw-r--r-- | src/gui/painting/qplatformbackingstore.h | 6 |
8 files changed, 252 insertions, 279 deletions
diff --git a/src/gui/kernel/qgenericpluginfactory.cpp b/src/gui/kernel/qgenericpluginfactory.cpp index 7e4727df8c..d7b9bfba06 100644 --- a/src/gui/kernel/qgenericpluginfactory.cpp +++ b/src/gui/kernel/qgenericpluginfactory.cpp @@ -69,13 +69,13 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, */ QObject *QGenericPluginFactory::create(const QString& key, const QString &specification) { +#if (!defined(Q_OS_WIN32) || defined(QT_SHARED)) && !defined(QT_NO_LIBRARY) const QString driver = key.toLower(); - -#if !defined(Q_OS_WIN32) || defined(QT_SHARED) -#ifndef QT_NO_LIBRARY if (QObject *object = qLoadPlugin1<QObject, QGenericPlugin>(loader(), driver, specification)) return object; -#endif +#else // (!Q_OS_WIN32 || QT_SHARED) && !QT_NO_LIBRARY + Q_UNUSED(key) + Q_UNUSED(specification) #endif return 0; } diff --git a/src/gui/kernel/qinputdevicemanager.cpp b/src/gui/kernel/qinputdevicemanager.cpp index d0dd8a4e7c..dbdb03adbb 100644 --- a/src/gui/kernel/qinputdevicemanager.cpp +++ b/src/gui/kernel/qinputdevicemanager.cpp @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE QInputDeviceManager::QInputDeviceManager(QObject *parent) : QObject(*new QInputDeviceManagerPrivate, parent) { + qRegisterMetaType<DeviceType>(); } int QInputDeviceManager::deviceCount(DeviceType type) const diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h index 15c84d1a82..d64793c23c 100644 --- a/src/gui/kernel/qinputdevicemanager_p.h +++ b/src/gui/kernel/qinputdevicemanager_p.h @@ -77,4 +77,6 @@ signals: QT_END_NAMESPACE +Q_DECLARE_METATYPE(QInputDeviceManager::DeviceType) + #endif // QINPUTDEVICEMANAGER_P_H diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index 7113345a75..b2025faaf1 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -175,141 +175,156 @@ public: this->shareContext = qt_gl_global_share_context(); } - ~QOpenGLWindowPrivate() - { - Q_Q(QOpenGLWindow); - if (q->isValid()) { - q->makeCurrent(); // this works even when the platformwindow is destroyed - paintDevice.reset(0); - fbo.reset(0); - blitter.destroy(); - q->doneCurrent(); - } - } + ~QOpenGLWindowPrivate(); static QOpenGLWindowPrivate *get(QOpenGLWindow *w) { return w->d_func(); } - void bindFBO() - { - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); - else - QOpenGLFramebufferObject::bindDefault(); + void bindFBO(); + void initialize(); + + void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; + void endPaint() Q_DECL_OVERRIDE; + void flush(const QRegion ®ion) Q_DECL_OVERRIDE; + + QOpenGLWindow::UpdateBehavior updateBehavior; + bool hasFboBlit; + QScopedPointer<QOpenGLContext> context; + QOpenGLContext *shareContext; + QScopedPointer<QOpenGLFramebufferObject> fbo; + QScopedPointer<QOpenGLWindowPaintDevice> paintDevice; + QOpenGLTextureBlitter blitter; + QColor backgroundColor; + QScopedPointer<QOffscreenSurface> offscreenSurface; +}; + +QOpenGLWindowPrivate::~QOpenGLWindowPrivate() +{ + Q_Q(QOpenGLWindow); + if (q->isValid()) { + q->makeCurrent(); // this works even when the platformwindow is destroyed + paintDevice.reset(0); + fbo.reset(0); + blitter.destroy(); + q->doneCurrent(); } +} - void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE - { - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - - if (!context) { - context.reset(new QOpenGLContext); - context->setShareContext(shareContext); - context->setFormat(q->requestedFormat()); - context->setScreen(q->screen()); - if (!context->create()) - qWarning("QOpenGLWindow::beginPaint: Failed to create context"); - if (!context->makeCurrent(q)) - qWarning("QOpenGLWindow::beginPaint: Failed to make context current"); - - paintDevice.reset(new QOpenGLWindowPaintDevice(q)); - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) - hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); - - q->initializeGL(); - } else { - context->makeCurrent(q); - } +void QOpenGLWindowPrivate::initialize() +{ + Q_Q(QOpenGLWindow); - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - const QSize deviceSize(deviceWidth, deviceHeight); - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (!fbo || fbo->size() != deviceSize) { - QOpenGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - if (q->requestedFormat().samples() > 0) { - if (updateBehavior != QOpenGLWindow::PartialUpdateBlend) - fboFormat.setSamples(q->requestedFormat().samples()); - else - qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); - } - fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); - markWindowAsDirty(); + if (context) + return; + + context.reset(new QOpenGLContext); + context->setShareContext(shareContext); + context->setFormat(q->requestedFormat()); + if (!context->create()) + qWarning("QOpenGLWindow::beginPaint: Failed to create context"); + if (!context->makeCurrent(q)) + qWarning("QOpenGLWindow::beginPaint: Failed to make context current"); + + paintDevice.reset(new QOpenGLWindowPaintDevice(q)); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) + hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); + + q->initializeGL(); +} + +void QOpenGLWindowPrivate::beginPaint(const QRegion ®ion) +{ + Q_UNUSED(region); + Q_Q(QOpenGLWindow); + + initialize(); + context->makeCurrent(q); + + const int deviceWidth = q->width() * q->devicePixelRatio(); + const int deviceHeight = q->height() * q->devicePixelRatio(); + const QSize deviceSize(deviceWidth, deviceHeight); + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { + if (!fbo || fbo->size() != deviceSize) { + QOpenGLFramebufferObjectFormat fboFormat; + fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + if (q->requestedFormat().samples() > 0) { + if (updateBehavior != QOpenGLWindow::PartialUpdateBlend) + fboFormat.setSamples(q->requestedFormat().samples()); + else + qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); } - } else { + fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); markWindowAsDirty(); } + } else { + markWindowAsDirty(); + } - paintDevice->setSize(QSize(deviceWidth, deviceHeight)); - paintDevice->setDevicePixelRatio(q->devicePixelRatio()); - context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); + paintDevice->setSize(QSize(deviceWidth, deviceHeight)); + paintDevice->setDevicePixelRatio(q->devicePixelRatio()); + context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); + context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - q->paintUnderGL(); + q->paintUnderGL(); - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); - } + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->bind(); +} - void endPaint() Q_DECL_OVERRIDE - { - Q_Q(QOpenGLWindow); - - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->release(); - - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - QOpenGLExtensions extensions(context.data()); - extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle()); - extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject()); - extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, - 0, 0, deviceWidth, deviceHeight, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { - context->functions()->glEnable(GL_BLEND); - context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - if (!blitter.isCreated()) - blitter.create(); +void QOpenGLWindowPrivate::endPaint() +{ + Q_Q(QOpenGLWindow); + + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->release(); - QRect windowRect(QPoint(0, 0), fbo->size()); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); - blitter.bind(); - blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); - blitter.release(); + context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) - context->functions()->glDisable(GL_BLEND); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { + const int deviceWidth = q->width() * q->devicePixelRatio(); + const int deviceHeight = q->height() * q->devicePixelRatio(); + QOpenGLExtensions extensions(context.data()); + extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle()); + extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject()); + extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, + 0, 0, deviceWidth, deviceHeight, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { + if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { + context->functions()->glEnable(GL_BLEND); + context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } + if (!blitter.isCreated()) + blitter.create(); - q->paintOverGL(); - } + QRect windowRect(QPoint(0, 0), fbo->size()); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); + blitter.bind(); + blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); + blitter.release(); - void flush(const QRegion ®ion) Q_DECL_OVERRIDE - { - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - context->swapBuffers(q); - emit q->frameSwapped(); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) + context->functions()->glDisable(GL_BLEND); } - QOpenGLWindow::UpdateBehavior updateBehavior; - bool hasFboBlit; - QScopedPointer<QOpenGLContext> context; - QOpenGLContext *shareContext; - QScopedPointer<QOpenGLFramebufferObject> fbo; - QScopedPointer<QOpenGLWindowPaintDevice> paintDevice; - QOpenGLTextureBlitter blitter; - QColor backgroundColor; - QScopedPointer<QOffscreenSurface> offscreenSurface; -}; + q->paintOverGL(); +} + +void QOpenGLWindowPrivate::bindFBO() +{ + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->bind(); + else + QOpenGLFramebufferObject::bindDefault(); +} + +void QOpenGLWindowPrivate::flush(const QRegion ®ion) +{ + Q_UNUSED(region); + Q_Q(QOpenGLWindow); + context->swapBuffers(q); + emit q->frameSwapped(); +} void QOpenGLWindowPaintDevice::ensureActiveTarget() { @@ -632,6 +647,8 @@ void QOpenGLWindow::paintEvent(QPaintEvent *event) void QOpenGLWindow::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); + Q_D(QOpenGLWindow); + d->initialize(); resizeGL(width(), height()); } diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 5f1b25e189..9b4eabc552 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -38,22 +38,6 @@ QT_BEGIN_NAMESPACE -typedef void (*qt_qimageScaleFunc)(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -static void qt_qimageScaleAARGB(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -static void qt_qimageScaleAARGBA(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -qt_qimageScaleFunc qt_qimageScaleArgb = qt_qimageScaleAARGBA; -qt_qimageScaleFunc qt_qimageScaleRgb = qt_qimageScaleAARGB; - - /* * Copyright (C) 2004, 2005 Daniel M. Duley * @@ -115,13 +99,6 @@ using namespace QImageScale; // Code ported from Imlib... // -// FIXME: replace with qRed, etc... These work on pointers to pixels, not -// pixel values -#define A_VAL(p) (qAlpha(*p)) -#define R_VAL(p) (qRed(*p)) -#define G_VAL(p) (qGreen(*p)) -#define B_VAL(p) (qBlue(*p)) - const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh) { @@ -381,46 +358,25 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, } } -inline static void qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b, int &a) -{ - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; - a = A_VAL(pix) * xap; - int j; - for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ - pix++; - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - a += A_VAL(pix) * Cx; - } - pix++; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; -} - -inline static void qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b, int &a) +inline static void qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b, int &a) { - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - a = A_VAL(pix) * yap; + r = qRed(*pix) * xyap; + g = qGreen(*pix) * xyap; + b = qBlue(*pix) * xyap; + a = qAlpha(*pix) * xyap; int j; - for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ - pix += sow; - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - a += A_VAL(pix) * Cy; - } - pix += sow; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; + for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) { + pix += step; + r += qRed(*pix) * Cxy; + g += qGreen(*pix) * Cxy; + b += qBlue(*pix) * Cxy; + a += qAlpha(*pix) * Cxy; + } + pix += step; + r += qRed(*pix) * j; + g += qGreen(*pix) * j; + b += qBlue(*pix) * j; + a += qAlpha(*pix) * j; } static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, @@ -443,12 +399,12 @@ static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b, a; - qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, r, g, b, a); + qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, r, g, b, a); int xap = xapoints[x]; if (xap > 0) { int rr, gg, bb, aa; - qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb, aa); + qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa); r = r * (256 - xap); g = g * (256 - xap); @@ -484,12 +440,12 @@ static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b, a; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, r, g, b, a); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, r, g, b, a); int yap = yapoints[dyy + y]; if (yap > 0) { int rr, gg, bb, aa; - qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, rr, gg, bb, aa); + qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa); r = r * (256 - yap); g = g * (256 - yap); @@ -528,7 +484,7 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int rx, gx, bx, ax; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); int r = ((rx>>4) * yap); int g = ((gx>>4) * yap); @@ -538,14 +494,14 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); r += ((rx>>4) * Cy); g += ((gx>>4) * Cy); b += ((bx>>4) * Cy); a += ((ax>>4) * Cy); } sptr += sow; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); r += ((rx>>4) * j); g += ((gx>>4) * j); @@ -609,40 +565,22 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, } -inline static void qt_qimageScaleAARGB_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b) +inline static void qt_qimageScaleAARGB_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b) { - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; + r = qRed(*pix) * xyap; + g = qGreen(*pix) * xyap; + b = qBlue(*pix) * xyap; int j; - for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ - pix++; - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - } - pix++; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; -} - -inline static void qt_qimageScaleAARGB_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b) -{ - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - int j; - for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ - pix += sow; - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - } - pix += sow; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; + for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) { + pix += step; + r += qRed(*pix) * Cxy; + g += qGreen(*pix) * Cxy; + b += qBlue(*pix) * Cxy; + } + pix += step; + r += qRed(*pix) * j; + g += qGreen(*pix) * j; + b += qBlue(*pix) * j; } static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, @@ -665,12 +603,12 @@ static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int * for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b; - qt_qimageScaleAARGB_helper_y(sptr, yap, Cy, sow, r, g, b); + qt_qimageScaleAARGB_helper(sptr, yap, Cy, sow, r, g, b); int xap = xapoints[x]; if (xap > 0) { int rr, bb, gg; - qt_qimageScaleAARGB_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb); + qt_qimageScaleAARGB_helper(sptr + 1, yap, Cy, sow, rr, gg, bb); r = r * (256 - xap); g = g * (256 - xap); @@ -704,12 +642,12 @@ static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int * const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, r, g, b); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, r, g, b); int yap = yapoints[dyy + y]; if (yap > 0) { int rr, bb, gg; - qt_qimageScaleAARGB_helper_x(sptr + sow, xap, Cx, rr, gg, bb); + qt_qimageScaleAARGB_helper(sptr + sow, xap, Cx, 1, rr, gg, bb); r = r * (256 - yap); g = g * (256 - yap); @@ -745,7 +683,7 @@ static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int rx, gx, bx; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); int r = (rx >> 4) * yap; int g = (gx >> 4) * yap; @@ -754,14 +692,14 @@ static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); r += (rx >> 4) * Cy; g += (gx >> 4) * Cy; b += (bx >> 4) * Cy; } sptr += sow; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); r += (rx >> 4) * j; g += (gx >> 4) * j; @@ -794,11 +732,11 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh) } if (src.hasAlphaChannel()) - qt_qimageScaleArgb(scaleinfo, (unsigned int *)buffer.scanLine(0), - 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); + qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), + 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); else - qt_qimageScaleRgb(scaleinfo, (unsigned int *)buffer.scanLine(0), - 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); + qt_qimageScaleAARGB(scaleinfo, (unsigned int *)buffer.scanLine(0), + 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); qimageFreeScaleInfo(scaleinfo); return buffer; diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp index 565ea4daa1..303e0fd980 100644 --- a/src/gui/painting/qimagescale_sse4.cpp +++ b/src/gui/painting/qimagescale_sse4.cpp @@ -41,33 +41,17 @@ QT_BEGIN_NAMESPACE using namespace QImageScale; -inline static __m128i qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, const __m128i vxap, const __m128i vCx) +inline static __m128i qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, const __m128i vxyap, const __m128i vCxy) { __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - __m128i vx = _mm_mullo_epi32(vpix, vxap); + __m128i vx = _mm_mullo_epi32(vpix, vxyap); int i; - for (i = (1 << 14) - xap; i > Cx; i -= Cx) { - pix++; + for (i = (1 << 14) - xyap; i > Cxy; i -= Cxy) { + pix += step; vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCx)); + vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCxy)); } - pix++; - vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); - return vx; -} - -inline static __m128i qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, const __m128i vyap, const __m128i vCy) -{ - __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - __m128i vx = _mm_mullo_epi32(vpix, vyap); - int i; - for (i = (1 << 14) - yap; i > Cy; i -= Cy) { - pix += sow; - vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCy)); - } - pix += sow; + pix += step; vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); return vx; @@ -97,13 +81,13 @@ void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *d unsigned int *dptr = dest + dx + ((y + dy) * dow); for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, vyap, vCy); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, vyap, vCy); int xap = xapoints[x]; if (xap > 0) { const __m128i vxap = _mm_set1_epi32(xap); const __m128i vinvxap = _mm_sub_epi32(v256, vxap); - __m128i vr = qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, vyap, vCy); + __m128i vr = qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow, vyap, vCy); vx = _mm_mullo_epi32(vx, vinvxap); vr = _mm_mullo_epi32(vr, vxap); @@ -145,13 +129,13 @@ void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *d const __m128i vxap = _mm_set1_epi32(xap); const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); int yap = yapoints[dyy + y]; if (yap > 0) { const __m128i vyap = _mm_set1_epi32(yap); const __m128i vinvyap = _mm_sub_epi32(v256, vyap); - __m128i vr = qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, vxap, vCx); + __m128i vr = qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, vxap, vCx); vx = _mm_mullo_epi32(vx, vinvyap); vr = _mm_mullo_epi32(vr, vyap); @@ -194,17 +178,17 @@ void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest, const __m128i vxap = _mm_set1_epi32(xap); const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); __m128i vr = _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vyap); int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vCy)); } sptr += sow; - vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), _mm_set1_epi32(j))); vr = _mm_srli_epi32(vr, 24); diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 14a9429c71..62492980de 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -83,9 +83,10 @@ public: struct QBackingstoreTextureInfo { - QWidget *widget; // may be null + void *source; // may be null GLuint textureId; QRect rect; + QRect clipRect; QPlatformTextureList::Flags flags; }; @@ -124,10 +125,10 @@ GLuint QPlatformTextureList::textureId(int index) const return d->textures.at(index).textureId; } -QWidget *QPlatformTextureList::widget(int index) +void *QPlatformTextureList::source(int index) { Q_D(const QPlatformTextureList); - return d->textures.at(index).widget; + return d->textures.at(index).source; } QPlatformTextureList::Flags QPlatformTextureList::flags(int index) const @@ -142,6 +143,12 @@ QRect QPlatformTextureList::geometry(int index) const return d->textures.at(index).rect; } +QRect QPlatformTextureList::clipRect(int index) const +{ + Q_D(const QPlatformTextureList); + return d->textures.at(index).clipRect; +} + void QPlatformTextureList::lock(bool on) { Q_D(QPlatformTextureList); @@ -157,13 +164,15 @@ bool QPlatformTextureList::isLocked() const return d->locked; } -void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags) +void QPlatformTextureList::appendTexture(void *source, GLuint textureId, const QRect &geometry, + const QRect &clipRect, Flags flags) { Q_D(QPlatformTextureList); QBackingstoreTextureInfo bi; - bi.widget = widget; + bi.source = source; bi.textureId = textureId; bi.rect = geometry; + bi.clipRect = clipRect; bi.flags = flags; d->textures.append(bi); } @@ -198,7 +207,7 @@ void QPlatformTextureList::clear() #ifndef QT_NO_OPENGL -static QRect deviceRect(const QRect &rect, QWindow *window) +static inline QRect deviceRect(const QRect &rect, QWindow *window) { QRect deviceRect(rect.topLeft() * window->devicePixelRatio(), rect.size() * window->devicePixelRatio()); @@ -219,6 +228,32 @@ static QRegion deviceRegion(const QRegion ®ion, QWindow *window) return deviceRegion; } +static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) +{ + return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1, + topLeftRect.width(), topLeftRect.height()); +} + +static void blit(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect, + QOpenGLTextureBlitter *blitter) +{ + const QRect rectInWindow = textures->geometry(idx); + QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); + const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); + + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(deviceRect(clippedRectInWindow, window), + deviceWindowRect); + + const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window), + deviceRect(rectInWindow, window).size(), + QOpenGLTextureBlitter::OriginBottomLeft); + + blitter->blit(textures->textureId(idx), target, source); +} + /*! Flushes the given \a region from the specified \a window onto the screen, and composes it with the specified \a textures. @@ -254,15 +289,12 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i d_ptr->blitter->bind(); - QRect windowRect(QPoint(), window->size() * window->devicePixelRatio()); + const QRect deviceWindowRect = deviceRect(QRect(QPoint(), window->size()), window); // Textures for renderToTexture widgets. for (int i = 0; i < textures->count(); ++i) { - if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QRect targetRect = deviceRect(textures->geometry(i), window); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); - d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); - } + if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) + blit(textures, i, window, deviceWindowRect, d_ptr->blitter); } funcs->glEnable(GL_BLEND); @@ -272,6 +304,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // semi-transparency even when it is not wanted. funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + // Backingstore texture with the normal widgets. GLuint textureId = 0; QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft; if (QPlatformGraphicsBuffer *graphicsBuffer = this->graphicsBuffer()) { @@ -307,7 +340,6 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i origin = QOpenGLTextureBlitter::OriginBottomLeft; textureId = d_ptr->textureId; } else { - // Backingstore texture with the normal widgets. TextureFlags flags = 0; textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &flags); d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0; @@ -316,7 +348,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i } if (textureId) { - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), windowRect); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), deviceWindowRect); if (d_ptr->needsSwizzle) d_ptr->blitter->setSwizzleRB(true); d_ptr->blitter->blit(textureId, target, origin); @@ -326,11 +358,8 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set. for (int i = 0; i < textures->count(); ++i) { - if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QRect targetRect = deviceRect(textures->geometry(i), window); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); - d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); - } + if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) + blit(textures, i, window, deviceWindowRect, d_ptr->blitter); } funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index ae7314b6d0..eac97e9cf6 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -82,12 +82,14 @@ public: bool isEmpty() const { return count() == 0; } GLuint textureId(int index) const; QRect geometry(int index) const; - QWidget *widget(int index); + QRect clipRect(int index) const; + void *source(int index); Flags flags(int index) const; void lock(bool on); bool isLocked() const; - void appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags = 0); + void appendTexture(void *source, GLuint textureId, const QRect &geometry, + const QRect &clipRect = QRect(), Flags flags = 0); void clear(); Q_SIGNALS: |