diff options
Diffstat (limited to 'src/quick/scenegraph/util/qsgtexture.cpp')
-rw-r--r-- | src/quick/scenegraph/util/qsgtexture.cpp | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 69edfab379..abd9d480c5 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -671,12 +671,28 @@ void QSGPlainTexture::bind() bindTime = qsg_renderer_timer.nsecsElapsed(); // ### TODO: check for out-of-memory situations... - int w = m_image.width(); - int h = m_image.height(); QImage tmp = (m_image.format() == QImage::Format_RGB32 || m_image.format() == QImage::Format_ARGB32_Premultiplied) ? m_image : m_image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + + // Downscale the texture to fit inside the max texture limit if it is too big. + // It would be better if the image was already downscaled to the right size, + // but this information is not always available at that time, so as a last + // resort we can do it here. Texture coordinates are normalized, so it + // won't cause any problems and actual texture sizes will be written + // based on QSGTexture::textureSize which is updated after this, so that + // should be ok. + int max; + if (QSGRenderContext *rc = QSGRenderContext::from(context)) + max = rc->maxTextureSize(); + else + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); + if (tmp.width() > max || tmp.height() > max) { + tmp = tmp.scaled(qMin(max, tmp.width()), qMin(max, tmp.height()), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + m_texture_size = tmp.size(); + } + if (tmp.width() * 4 != tmp.bytesPerLine()) tmp = tmp.copy(); @@ -726,7 +742,7 @@ void QSGPlainTexture::bind() if (profileFrames) swizzleTime = qsg_renderer_timer.nsecsElapsed(); - funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, externalFormat, GL_UNSIGNED_BYTE, tmp.constBits()); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_texture_size.width(), m_texture_size.height(), 0, externalFormat, GL_UNSIGNED_BYTE, tmp.constBits()); qint64 uploadTime = 0; if (profileFrames) @@ -741,7 +757,7 @@ void QSGPlainTexture::bind() if (profileFrames) { mipmapTime = qsg_renderer_timer.nsecsElapsed(); qCDebug(QSG_LOG_TIME_TEXTURE, - "plain texture uploaded in: %dms (%dx%d), bind=%d, convert=%d, swizzle=%d (%s->%s), upload=%d, mipmap=%d", + "plain texture uploaded in: %dms (%dx%d), bind=%d, convert=%d, swizzle=%d (%s->%s), upload=%d, mipmap=%d%s", int(mipmapTime / 1000000), m_texture_size.width(), m_texture_size.height(), int(bindTime / 1000000), @@ -750,7 +766,8 @@ void QSGPlainTexture::bind() (externalFormat == GL_BGRA ? "BGRA" : "RGBA"), (internalFormat == GL_BGRA ? "BGRA" : "RGBA"), int((uploadTime - swizzleTime)/1000000), - int((mipmapTime - uploadTime)/1000000)); + int((mipmapTime - uploadTime)/1000000), + m_texture_size != m_image.size() ? " (scaled to GL_MAX_TEXTURE_SIZE)" : ""); } Q_QUICK_SG_PROFILE(QQuickProfiler::SceneGraphTexturePrepare, ( @@ -760,7 +777,6 @@ void QSGPlainTexture::bind() uploadTime - swizzleTime, qsg_renderer_timer.nsecsElapsed() - uploadTime)); - m_texture_size = QSize(w, h); m_texture_rect = QRectF(0, 0, 1, 1); m_dirty_bind_options = false; |