This way they will at least render.
[ChangeLog][QtQuick] Images exceeding GL_MAX_TEXTURE_SIZE will be
downscaled to fit so they will still show.
Change-Id: I169ecac768036812b8e14265ec1a0a8902655666
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
QSet<QByteArray> exts = renderContext->openglContext()->extensions();
QByteArray all; foreach (const QByteArray &e, exts) all += ' ' + e;
qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS: " << all.constData();
+ qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << renderContext->maxTextureSize();
}
d->mutex.unlock();
, m_atlasManager(0)
, m_depthStencilManager(0)
, m_distanceFieldCacheManager(0)
+ , m_maxTextureSize(0)
, m_brokenIBOs(false)
, m_serializedRender(false)
, m_attachToGLContext(true)
*/
void QSGRenderContext::initialize(QOpenGLContext *context)
{
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
+
// Sanity check the surface format, in case it was overridden by the application
QSurfaceFormat requested = m_sg->defaultSurfaceFormat();
QSurfaceFormat actual = context->format();
m_sg->renderContextInitialized(this);
#ifdef Q_OS_LINUX
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
const char *vendor = (const char *) funcs->glGetString(GL_VENDOR);
if (strstr(vendor, "nouveau"))
m_brokenIBOs = true;
static QSGRenderContext *from(QOpenGLContext *context);
bool hasBrokenIndexBufferObjects() const { return m_brokenIBOs; }
+ int maxTextureSize() const { return m_maxTextureSize; }
Q_SIGNALS:
void initialized();
QSGDistanceFieldGlyphCacheManager *m_distanceFieldCacheManager;
QSet<QFontEngine *> m_fontEnginesToClean;
-
+ int m_maxTextureSize;
bool m_brokenIBOs;
bool m_serializedRender;
bool m_attachToGLContext;
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();
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)
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),
(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, (
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;
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ width: 200
+ height: 200
+
+ Image {
+ source: "toowide.png"
+ width: 100
+ height: 100
+ }
+
+ Image {
+ x: 100
+ source: "tootall.png"
+ width: 100
+ height: 100
+ }
+}
#include <QtGui/QPainter>
#include <QtGui/QImageReader>
#include <QQuickWindow>
+#include <QQuickView>
#include <QQuickImageProvider>
#include "../../shared/util.h"
void sourceSizeChanges();
void correctStatus();
void highdpi();
+ void hugeImages();
private:
QQmlEngine engine;
delete obj;
}
+void tst_qquickimage::hugeImages()
+{
+ QQuickView view;
+ view.setSource(testFileUrl("hugeImages.qml"));
+ view.setGeometry(0, 0, 200, 200);
+ view.create();
+
+ QImage contents = view.grabWindow();
+
+ QCOMPARE(contents.pixel(0, 0), qRgba(255, 0, 0, 255));
+ QCOMPARE(contents.pixel(99, 99), qRgba(255, 0, 0, 255));
+ QCOMPARE(contents.pixel(100, 0), qRgba(0, 0, 255, 255));
+ QCOMPARE(contents.pixel(199, 99), qRgba(0, 0, 255, 255));
+}
+
QTEST_MAIN(tst_qquickimage)
#include "tst_qquickimage.moc"