summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qplatformbackingstore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting/qplatformbackingstore.cpp')
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp97
1 files changed, 59 insertions, 38 deletions
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index 5b6c4bb83d..e5b06f499c 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -90,6 +90,7 @@ struct QBackingstoreTextureInfo
{
GLuint textureId;
QRect rect;
+ bool stacksOnTop;
};
Q_DECLARE_TYPEINFO(QBackingstoreTextureInfo, Q_MOVABLE_TYPE);
@@ -127,6 +128,12 @@ GLuint QPlatformTextureList::textureId(int index) const
return d->textures.at(index).textureId;
}
+bool QPlatformTextureList::stacksOnTop(int index) const
+{
+ Q_D(const QPlatformTextureList);
+ return d->textures.at(index).stacksOnTop;
+}
+
QRect QPlatformTextureList::geometry(int index) const
{
Q_D(const QPlatformTextureList);
@@ -148,12 +155,13 @@ bool QPlatformTextureList::isLocked() const
return d->locked;
}
-void QPlatformTextureList::appendTexture(GLuint textureId, const QRect &geometry)
+void QPlatformTextureList::appendTexture(GLuint textureId, const QRect &geometry, bool stacksOnTop)
{
Q_D(QPlatformTextureList);
QBackingstoreTextureInfo bi;
bi.textureId = textureId;
bi.rect = geometry;
+ bi.stacksOnTop = stacksOnTop;
d->textures.append(bi);
}
@@ -238,29 +246,39 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
QRect windowRect(QPoint(), window->size() * window->devicePixelRatio());
+ // Textures for renderToTexture widgets.
for (int i = 0; i < textures->count(); ++i) {
- GLuint textureId = textures->textureId(i);
- funcs->glBindTexture(GL_TEXTURE_2D, textureId);
-
- QRect targetRect = deviceRect(textures->geometry(i), window);
- QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect);
- d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
+ if (!textures->stacksOnTop(i)) {
+ QRect targetRect = deviceRect(textures->geometry(i), window);
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect);
+ d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft);
+ }
}
- GLuint textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize);
- if (!textureId)
- return;
-
funcs->glEnable(GL_BLEND);
funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), windowRect);
- d_ptr->blitter->setSwizzleRB(true);
- d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
- d_ptr->blitter->setSwizzleRB(false);
+ // Backingstore texture with the normal widgets.
+ GLuint textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize);
+ if (textureId) {
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), windowRect);
+ d_ptr->blitter->setSwizzleRB(true);
+ d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
+ d_ptr->blitter->setSwizzleRB(false);
+ }
+
+ // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
+ for (int i = 0; i < textures->count(); ++i) {
+ if (textures->stacksOnTop(i)) {
+ QRect targetRect = deviceRect(textures->geometry(i), window);
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect);
+ d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft);
+ }
+ }
funcs->glDisable(GL_BLEND);
d_ptr->blitter->release();
+
context->swapBuffers(window);
}
@@ -321,8 +339,8 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
#endif
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
const_cast<uchar*>(image.constBits()));
@@ -334,29 +352,32 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
QRect rect = dirtyRegion.boundingRect() & imageRect;
#ifndef QT_OPENGL_ES_2
- funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- image.constScanLine(rect.y()) + rect.x() * 4);
- funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-#else
- // if the rect is wide enough it's cheaper to just
- // extend it instead of doing an image copy
- if (rect.width() >= imageRect.width() / 2) {
- rect.setX(0);
- rect.setWidth(imageRect.width());
- }
-
- // if the sub-rect is full-width we can pass the image data directly to
- // OpenGL instead of copying, since there's no gap between scanlines
-
- if (rect.width() == imageRect.width()) {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- image.constScanLine(rect.y()));
- } else {
+ if (!QOpenGLContext::currentContext()->isOpenGLES()) {
+ funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- image.copy(rect).constBits());
- }
+ image.constScanLine(rect.y()) + rect.x() * 4);
+ funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ } else
#endif
+ {
+ // if the rect is wide enough it's cheaper to just
+ // extend it instead of doing an image copy
+ if (rect.width() >= imageRect.width() / 2) {
+ rect.setX(0);
+ rect.setWidth(imageRect.width());
+ }
+
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there's no gap between scanlines
+
+ if (rect.width() == imageRect.width()) {
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ image.constScanLine(rect.y()));
+ } else {
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ image.copy(rect).constBits());
+ }
+ }
}
return d_ptr->textureId;