aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/util/qsgtexture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph/util/qsgtexture.cpp')
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp114
1 files changed, 104 insertions, 10 deletions
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index 16cc46113d..cd95d9f445 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -48,7 +48,7 @@
#include <private/qqmlprofilerservice_p.h>
#include <private/qqmlglobal_p.h>
-#if defined(Q_OS_LINUX) && !defined(Q_OS_LINUX_ANDROID)
+#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
#define CAN_BACKTRACE_EXECINFO
#endif
@@ -65,6 +65,20 @@
#include <QHash>
#endif
+#ifndef QT_NO_DEBUG
+static bool qsg_leak_check = !qgetenv("QML_LEAK_CHECK").isEmpty();
+#endif
+
+#ifndef QSG_NO_RENDERER_TIMING
+static bool qsg_render_timing = !qgetenv("QML_RENDERER_TIMING").isEmpty();
+static QElapsedTimer qsg_renderer_timer;
+#endif
+
+#ifndef GL_BGRA
+#define GL_BGRA 0x80E1
+#endif
+
+
QT_BEGIN_NAMESPACE
inline static bool isPowerOfTwo(int x)
@@ -172,7 +186,7 @@ static void qt_debug_remove_texture(QSGTexture* texture)
--qt_debug_texture_count;
if (qt_debug_texture_count < 0)
- qDebug("Material destroyed after qt_debug_print_texture_count() was called.");
+ qDebug("Texture destroyed after qt_debug_print_texture_count() was called.");
}
#endif // QT_NO_DEBUG
@@ -218,6 +232,8 @@ static void qt_debug_remove_texture(QSGTexture* texture)
If the texture is used in such a way that atlas is not preferable,
the function removedFromAtlas() can be used to extract a
non-atlassed copy.
+
+ \sa {Scene Graph - Rendering FBOs}, {Scene Graph - Rendering FBOs in a thread}
*/
/*!
@@ -259,7 +275,8 @@ QSGTexture::QSGTexture()
: QObject(*(new QSGTexturePrivate))
{
#ifndef QT_NO_DEBUG
- qt_debug_add_texture(this);
+ if (qsg_leak_check)
+ qt_debug_add_texture(this);
#endif
}
@@ -269,7 +286,8 @@ QSGTexture::QSGTexture()
QSGTexture::~QSGTexture()
{
#ifndef QT_NO_DEBUG
- qt_debug_remove_texture(this);
+ if (qsg_leak_check)
+ qt_debug_remove_texture(this);
#endif
}
@@ -513,6 +531,7 @@ QSGPlainTexture::QSGPlainTexture()
, m_dirty_bind_options(false)
, m_owns_texture(true)
, m_mipmaps_generated(false)
+ , m_retain_image(false)
{
}
@@ -523,7 +542,6 @@ QSGPlainTexture::~QSGPlainTexture()
glDeleteTextures(1, &m_texture_id);
}
-#ifdef QT_OPENGL_ES
void qsg_swizzleBGRAToRGBA(QImage *image)
{
const int width = image->width();
@@ -534,7 +552,6 @@ void qsg_swizzleBGRAToRGBA(QImage *image)
p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
}
}
-#endif
void QSGPlainTexture::setImage(const QImage &image)
{
@@ -596,14 +613,30 @@ void QSGPlainTexture::bind()
m_dirty_texture = false;
+#ifndef QSG_NO_RENDERER_TIMING
+ if (qsg_render_timing)
+ qsg_renderer_timer.start();
+#endif
if (m_image.isNull()) {
- if (m_texture_id && m_owns_texture)
+ if (m_texture_id && m_owns_texture) {
glDeleteTextures(1, &m_texture_id);
+#ifndef QSG_NO_RENDERER_TIMING
+ if (qsg_render_timing) {
+ printf(" - texture deleted in %dms (size: %dx%d)\n",
+ (int) qsg_renderer_timer.elapsed(),
+ m_texture_size.width(),
+ m_texture_size.height());
+ }
+#endif
+ }
m_texture_id = 0;
m_texture_size = QSize();
m_has_mipmaps = false;
m_has_alpha = false;
+
+
+
return;
}
@@ -611,6 +644,12 @@ void QSGPlainTexture::bind()
glGenTextures(1, &m_texture_id);
glBindTexture(GL_TEXTURE_2D, m_texture_id);
+#ifndef QSG_NO_RENDERER_TIMING
+ int bindTime = 0;
+ if (qsg_render_timing)
+ bindTime = qsg_renderer_timer.elapsed();
+#endif
+
// ### TODO: check for out-of-memory situations...
int w = m_image.width();
int h = m_image.height();
@@ -619,14 +658,46 @@ void QSGPlainTexture::bind()
? m_image
: m_image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+#ifndef QSG_NO_RENDERER_TIMING
+ int convertTime = 0;
+ if (qsg_render_timing)
+ convertTime = qsg_renderer_timer.elapsed();
+#endif
+
updateBindOptions(m_dirty_bind_options);
+ GLenum externalFormat = GL_RGBA;
+ GLenum internalFormat = GL_RGBA;
+
+ const char *extensions = (const char *) glGetString(GL_EXTENSIONS);
+ if (strstr(extensions, "GL_EXT_bgra")) {
+ externalFormat = GL_BGRA;
#ifdef QT_OPENGL_ES
+ internalFormat = GL_BGRA;
+#endif
+ } else if (strstr(extensions, "GL_APPLE_texture_format_BGRA8888")) {
+ externalFormat = GL_BGRA;
+ } else if (strstr(extensions, "GL_EXT_texture_format_BGRA8888")
+ || strstr(extensions, "GL_IMG_texture_format_BGRA8888")) {
+ externalFormat = GL_BGRA;
+ internalFormat = GL_BGRA;
+ } else {
qsg_swizzleBGRAToRGBA(&tmp);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp.constBits());
-#else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, tmp.constBits());
+ }
+
+#ifndef QSG_NO_RENDERER_TIMING
+ int swizzleTime = 0;
+ if (qsg_render_timing)
+ swizzleTime = qsg_renderer_timer.elapsed();
#endif
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, externalFormat, GL_UNSIGNED_BYTE, tmp.constBits());
+
+#ifndef QSG_NO_RENDERER_TIMING
+ int uploadTime = 0;
+ if (qsg_render_timing)
+ uploadTime = qsg_renderer_timer.elapsed();
+#endif
+
if (m_has_mipmaps) {
QOpenGLContext *ctx = QOpenGLContext::currentContext();
@@ -634,10 +705,33 @@ void QSGPlainTexture::bind()
m_mipmaps_generated = true;
}
+#ifndef QSG_NO_RENDERER_TIMING
+ int mipmapTime = 0;
+ if (qsg_render_timing) {
+ mipmapTime = qsg_renderer_timer.elapsed();
+
+ printf(" - plaintexture(%dx%d) bind=%d, convert=%d, swizzle=%d (%s->%s), upload=%d, mipmap=%d, total=%d\n",
+ m_texture_size.width(), m_texture_size.height(),
+ bindTime,
+ convertTime - bindTime,
+ swizzleTime - convertTime,
+ externalFormat == GL_BGRA ? "BGRA" : "RGBA",
+ internalFormat == GL_BGRA ? "BGRA" : "RGBA",
+ uploadTime - swizzleTime,
+ mipmapTime - uploadTime,
+ (int) qsg_renderer_timer.elapsed());
+
+ }
+
+#endif
+
+
m_texture_size = QSize(w, h);
m_texture_rect = QRectF(0, 0, 1, 1);
m_dirty_bind_options = false;
+ if (!m_retain_image)
+ m_image = QImage();
}