aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/scenegraph/util/qsgtexture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/scenegraph/util/qsgtexture.cpp')
-rw-r--r--src/declarative/scenegraph/util/qsgtexture.cpp541
1 files changed, 0 insertions, 541 deletions
diff --git a/src/declarative/scenegraph/util/qsgtexture.cpp b/src/declarative/scenegraph/util/qsgtexture.cpp
deleted file mode 100644
index e2219e54f5..0000000000
--- a/src/declarative/scenegraph/util/qsgtexture.cpp
+++ /dev/null
@@ -1,541 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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, Nokia gives you certain additional
-** rights. These rights are described in the Nokia 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define GL_GLEXT_PROTOTYPES
-
-#include <private/qsgtexture_p.h>
-#include <qopenglfunctions.h>
-#include <private/qsgcontext_p.h>
-#include <qthread.h>
-#include <private/qdeclarativedebugtrace_p.h>
-
-#if !defined(QT_NO_DEBUG) && (defined(Q_OS_LINUX) || defined(Q_OS_MAC))
-#include <execinfo.h>
-#include <QHash>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-inline static bool isPowerOfTwo(int x)
-{
- // Assumption: x >= 1
- return x == (x & -x);
-}
-
-QSGTexturePrivate::QSGTexturePrivate()
- : wrapChanged(false)
- , filteringChanged(false)
- , horizontalWrap(QSGTexture::ClampToEdge)
- , verticalWrap(QSGTexture::ClampToEdge)
- , mipmapMode(QSGTexture::None)
- , filterMode(QSGTexture::Nearest)
-{
-}
-
-#ifndef QT_NO_DEBUG
-
-static int qt_debug_texture_count = 0;
-
-#if defined(Q_OS_LINUX) || defined (Q_OS_MAC)
-DEFINE_BOOL_CONFIG_OPTION(qmlDebugLeakBacktrace, QML_DEBUG_LEAK_BACKTRACE)
-
-#define BACKTRACE_SIZE 20
-class SGTextureTraceItem
-{
-public:
- void *backTrace[BACKTRACE_SIZE];
- size_t backTraceSize;
-};
-
-static QHash<QSGTexture*, SGTextureTraceItem*> qt_debug_allocated_textures;
-#endif
-
-inline static void qt_debug_print_texture_count()
-{
- qDebug("Number of leaked textures: %i", qt_debug_texture_count);
- qt_debug_texture_count = -1;
-
-#if defined(Q_OS_LINUX) || defined (Q_OS_MAC)
- if (qmlDebugLeakBacktrace()) {
- while (!qt_debug_allocated_textures.isEmpty()) {
- QHash<QSGTexture*, SGTextureTraceItem*>::Iterator it = qt_debug_allocated_textures.begin();
- QSGTexture* texture = it.key();
- SGTextureTraceItem* item = it.value();
-
- qt_debug_allocated_textures.erase(it);
-
- qDebug() << "------";
- qDebug() << "Leaked" << texture << "backtrace:";
-
- char** symbols = backtrace_symbols(item->backTrace, item->backTraceSize);
-
- if (symbols) {
- for (int i=0; i<(int) item->backTraceSize; i++)
- qDebug("Backtrace <%02d>: %s", i, symbols[i]);
- free(symbols);
- }
-
- qDebug() << "------";
-
- delete item;
- }
- }
-#endif
-}
-
-inline static void qt_debug_add_texture(QSGTexture* texture)
-{
-#if defined(Q_OS_LINUX) || defined (Q_OS_MAC)
- if (qmlDebugLeakBacktrace()) {
- SGTextureTraceItem* item = new SGTextureTraceItem;
- item->backTraceSize = backtrace(item->backTrace, BACKTRACE_SIZE);
- qt_debug_allocated_textures.insert(texture, item);
- }
-#else
- Q_UNUSED(texture);
-#endif // Q_OS_LINUX
-
- ++qt_debug_texture_count;
-
- static bool atexit_registered = false;
- if (!atexit_registered) {
- atexit(qt_debug_print_texture_count);
- atexit_registered = true;
- }
-}
-
-static void qt_debug_remove_texture(QSGTexture* texture)
-{
-#if defined(Q_OS_LINUX) || defined (Q_OS_MAC)
- if (qmlDebugLeakBacktrace()) {
- SGTextureTraceItem* item = qt_debug_allocated_textures.value(texture, 0);
- if (item) {
- qt_debug_allocated_textures.remove(texture);
- delete item;
- }
- }
-#else
- Q_UNUSED(texture)
-#endif
-
- --qt_debug_texture_count;
-
- if (qt_debug_texture_count < 0)
- qDebug("Material destroyed after qt_debug_print_texture_count() was called.");
-}
-
-#endif // QT_NO_DEBUG
-
-
-QSGTexture::QSGTexture()
- : QObject(*(new QSGTexturePrivate))
-{
-#ifndef QT_NO_DEBUG
- qt_debug_add_texture(this);
-#endif
-}
-
-QSGTexture::~QSGTexture()
-{
-#ifndef QT_NO_DEBUG
- qt_debug_remove_texture(this);
-#endif
-}
-
-
-/*!
- \fn void QSGTexture::bind()
-
- Call this function to bind this texture to the current texture
- target.
-
- Binding a texture may also include uploading the texture data from
- a previously set QImage.
-
- \warning This function can only be called from the rendering thread.
- */
-
-/*!
- This function returns a copy of the current texture which is removed
- from its atlas.
-
- The current texture remains unchanged, so texture coordinates do not
- need to be updated.
-
- Removing a texture from an atlas is primarily useful when passing
- it to a shader that operates on the texture coordinates 0-1 instead
- of the texture subrect inside the atlas.
-
- If the texture is not part of a texture atlas, this function returns 0.
-
- Implementations of this function are recommended to return the same instance
- for multiple calls to limit memory usage.
-
- \warning This function can only be called from the rendering thread.
- */
-
-QSGTexture *QSGTexture::removedFromAtlas() const
-{
- Q_ASSERT_X(!isAtlasTexture(), "QSGTexture::removedFromAtlas()", "Called on a non-atlas texture");
- return 0;
-}
-
-/*!
- Returns weither this texture is part of an atlas or not.
-
- The default implementation returns false.
- */
-bool QSGTexture::isAtlasTexture() const
-{
- return false;
-}
-
-/*!
- \fn int QSGTexture::textureId() const
-
- Returns the OpenGL texture id for this texture.
-
- The default value is 0, indicating that it is an invalid texture id.
-
- The function should at all times return the correct texture id.
-
- \warning This function can only be called from the rendering thread.
- */
-
-
-
-/*!
- Returns the rectangle inside textureSize() that this texture
- represents in normalized coordinates.
-
- The default implementation returns a rect at position (0, 0) with
- width and height of 1.
- */
-QRectF QSGTexture::textureSubRect() const
-{
- return QRectF(0, 0, 1, 1);
-}
-
-/*!
- \fn bool QSGTexture::hasMipmaps() const
-
- Returns true if the texture data contains mipmap levels.
- */
-
-
-/*!
- Sets the mipmap sampling mode to be used for the upcoming bind() call to \a filter.
-
- Setting the mipmap filtering has no effect it the texture does not have mipmaps.
-
- \sa hasMipmaps()
- */
-void QSGTexture::setMipmapFiltering(Filtering filter)
-{
- Q_D(QSGTexture);
- if (d->mipmapMode != (uint) filter) {
- d->mipmapMode = filter;
- d->filteringChanged = true;
- }
-}
-
-/*!
- Returns whether mipmapping should be used when sampling from this texture.
- */
-QSGTexture::Filtering QSGTexture::mipmapFiltering() const
-{
- return (QSGTexture::Filtering) d_func()->mipmapMode;
-}
-
-
-/*!
- Sets the sampling mode to be used for the upcoming bind() call to \a filter.
- */
-void QSGTexture::setFiltering(QSGTexture::Filtering filter)
-{
- Q_D(QSGTexture);
- if (d->filterMode != (uint) filter) {
- d->filterMode = filter;
- d->filteringChanged = true;
- }
-}
-
-QSGTexture::Filtering QSGTexture::filtering() const
-{
- return (QSGTexture::Filtering) d_func()->filterMode;
-}
-
-
-
-/*!
- Sets the horizontal wrap mode to be used for the upcoming bind() call to \a hwrap
- */
-
-void QSGTexture::setHorizontalWrapMode(WrapMode hwrap)
-{
- Q_D(QSGTexture);
- if ((uint) hwrap != d->horizontalWrap) {
- d->horizontalWrap = hwrap;
- d->wrapChanged = true;
- }
-}
-
-QSGTexture::WrapMode QSGTexture::horizontalWrapMode() const
-{
- return (QSGTexture::WrapMode) d_func()->horizontalWrap;
-}
-
-
-
-void QSGTexture::setVerticalWrapMode(WrapMode vwrap)
-{
- Q_D(QSGTexture);
- if ((uint) vwrap != d->verticalWrap) {
- d->verticalWrap = vwrap;
- d->wrapChanged = true;
- }
-}
-
-QSGTexture::WrapMode QSGTexture::verticalWrapMode() const
-{
- return (QSGTexture::WrapMode) d_func()->verticalWrap;
-}
-
-
-/*!
- Update the texture state to match the filtering, mipmap and wrap options
- currently set.
-
- If \a force is true, all properties will be updated regardless of weither
- they have changed or not.
- */
-void QSGTexture::updateBindOptions(bool force)
-{
- Q_D(QSGTexture);
- if (force || d->filteringChanged) {
- bool linear = d->filterMode == Linear;
- GLint minFilter = linear ? GL_LINEAR : GL_NEAREST;
- GLint magFilter = linear ? GL_LINEAR : GL_NEAREST;
-
- if (hasMipmaps()) {
- if (d->mipmapMode == Nearest)
- minFilter = linear ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST;
- else if (d->mipmapMode == Linear)
- minFilter = linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR;
- }
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
- d->filteringChanged = false;
- }
-
- if (force || d->wrapChanged) {
-#if !defined(QT_NO_DEBUG) && defined(QT_OPENGL_ES_2)
- if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat) {
- bool npotSupported = QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
- QSize size = textureSize();
- bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height());
- if (!npotSupported && isNpot)
- qWarning("Scene Graph: This system does not support the REPEAT wrap mode for non-power-of-two textures.");
- }
-#endif
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, d->horizontalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, d->verticalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
- d->wrapChanged = false;
- }
-}
-
-QSGPlainTexture::QSGPlainTexture()
- : QSGTexture()
- , m_texture_id(0)
- , m_has_alpha(false)
- , m_has_mipmaps(false)
- , m_dirty_bind_options(false)
- , m_owns_texture(true)
- , m_mipmaps_generated(false)
-{
-}
-
-
-QSGPlainTexture::~QSGPlainTexture()
-{
- if (m_texture_id && m_owns_texture)
- glDeleteTextures(1, &m_texture_id);
-}
-
-#ifdef QT_OPENGL_ES
-static void swizzleBGRAToRGBA(QImage *image)
-{
- const int width = image->width();
- const int height = image->height();
- for (int i = 0; i < height; ++i) {
- uint *p = (uint *) image->scanLine(i);
- for (int x = 0; x < width; ++x)
- p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
- }
-}
-#endif
-
-void QSGPlainTexture::setImage(const QImage &image)
-{
- m_image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
-#ifdef QT_OPENGL_ES
- swizzleBGRAToRGBA(&m_image);
-#endif
-
- m_texture_size = image.size();
- m_has_alpha = image.hasAlphaChannel();
- m_dirty_texture = true;
- m_dirty_bind_options = true;
- }
-
-int QSGPlainTexture::textureId() const
-{
- if (m_dirty_texture) {
- if (m_image.isNull()) {
- // The actual texture and id will be updated/deleted in a later bind()
- // or ~QSGPlainTexture so just keep it minimal here.
- return 0;
- } else {
- // Generate a texture id for use later and return it.
- glGenTextures(1, &const_cast<QSGPlainTexture *>(this)->m_texture_id);
- return m_texture_id;
- }
- }
- return m_texture_id;
-}
-
-void QSGPlainTexture::setTextureId(int id)
-{
- if (m_texture_id && m_owns_texture)
- glDeleteTextures(1, &m_texture_id);
-
- m_texture_id = id;
- m_dirty_texture = false;
- m_dirty_bind_options = true;
- m_image = QImage();
- m_mipmaps_generated = false;
-}
-
-void QSGPlainTexture::setHasMipmaps(bool mm)
-{
- m_has_mipmaps = mm;
- m_mipmaps_generated = false;
-}
-
-
-void QSGPlainTexture::bind()
-{
- if (!m_dirty_texture) {
- glBindTexture(GL_TEXTURE_2D, m_texture_id);
- if (m_has_mipmaps && !m_mipmaps_generated) {
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D);
- m_mipmaps_generated = true;
- }
- updateBindOptions(m_dirty_bind_options);
- m_dirty_bind_options = false;
- return;
- }
-
- m_dirty_texture = false;
-
-
- if (m_image.isNull()) {
- if (m_texture_id && m_owns_texture)
- glDeleteTextures(1, &m_texture_id);
- m_texture_id = 0;
- m_texture_size = QSize();
- m_has_mipmaps = false;
- m_has_alpha = false;
- return;
- }
-
- if (m_texture_id == 0)
- glGenTextures(1, &m_texture_id);
- glBindTexture(GL_TEXTURE_2D, m_texture_id);
-
- // ### TODO: check for out-of-memory situations...
- int w = m_image.width();
- int h = m_image.height();
-
-#ifdef QT_OPENGL_ES
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_image.constBits());
-#else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, m_image.constBits());
-#endif
-
- if (m_has_mipmaps) {
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D);
- m_mipmaps_generated = true;
- }
-
- m_texture_size = QSize(w, h);
- m_texture_rect = QRectF(0, 0, 1, 1);
-
- updateBindOptions(m_dirty_bind_options);
- m_dirty_bind_options = false;
-}
-
-
-/*!
- \class QSGDynamicTexture
- \brief The QSGDynamicTexture class serves as a baseclass for dynamically changing textures,
- such as content that is rendered to FBO's.
-
- To update the content of the texture, call updateTexture() explicitly. Simply calling bind()
- will not update the texture.
- */
-
-
-/*!
- \fn bool QSGDynamicTexture::updateTexture()
-
- Call this function to explicitely update the dynamic texture. Calling bind() will bind
- the content that was previously updated.
-
- The function returns true if the texture was changed as a resul of the update; otherwise
- returns false.
- */
-
-
-
-QT_END_NAMESPACE