diff options
Diffstat (limited to 'src/scenegraph')
-rw-r--r-- | src/scenegraph/convenience/texturematerial.cpp | 12 | ||||
-rw-r--r-- | src/scenegraph/convenience/texturematerial.h | 8 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qsgcontext.cpp | 61 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qsgcontext.h | 6 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qsgtexturemanager.cpp | 130 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qsgtexturemanager.h | 176 | ||||
-rw-r--r-- | src/scenegraph/coreapi/renderer.cpp | 4 | ||||
-rw-r--r-- | src/scenegraph/coreapi/renderer.h | 5 | ||||
-rw-r--r-- | src/scenegraph/scenegraph.pri | 4 |
9 files changed, 358 insertions, 48 deletions
diff --git a/src/scenegraph/convenience/texturematerial.cpp b/src/scenegraph/convenience/texturematerial.cpp index 021d4b1..8e03884 100644 --- a/src/scenegraph/convenience/texturematerial.cpp +++ b/src/scenegraph/convenience/texturematerial.cpp @@ -118,7 +118,7 @@ void TextureMaterialData::updateEffectState(Renderer *renderer, AbstractEffect * TextureMaterial *tx = static_cast<TextureMaterial *>(newEffect); TextureMaterial *oldTx = static_cast<TextureMaterial *>(oldEffect); - if (oldEffect == 0 || tx->texture() != oldTx->texture()) { + if (oldEffect == 0 || tx->texture().texture() != oldTx->texture().texture()) { renderer->setTexture(0, tx->texture()); oldEffect = 0; // Force filtering update. } @@ -131,7 +131,7 @@ void TextureMaterialData::updateEffectState(Renderer *renderer, AbstractEffect * } -void TextureMaterial::setTexture(const TextureReference *texture, bool opaque) +void TextureMaterial::setTexture(const QSGTextureRef &texture, bool opaque) { m_texture = texture; m_opaque = opaque; @@ -152,7 +152,7 @@ int TextureMaterial::compare(const AbstractEffect *o) const { Q_ASSERT(o && type() == o->type()); const TextureMaterial *other = static_cast<const TextureMaterial *>(o); - if (int diff = m_texture - other->texture()) + if (int diff = m_texture->textureId() - other->texture()->textureId()) return diff; return int(m_linear_filtering) - int(other->m_linear_filtering); } @@ -205,14 +205,14 @@ int TextureMaterialWithOpacity::compare(const AbstractEffect *o) const { Q_ASSERT(o && type() == o->type()); const TextureMaterialWithOpacity *other = static_cast<const TextureMaterialWithOpacity *>(o); - if (int diff = m_texture - other->texture()) + if (int diff = m_texture->textureId() - other->texture()->textureId()) return diff; if (int diff = int(m_linear_filtering) - int(other->m_linear_filtering)) return diff; return int(other->m_opacity < m_opacity) - int(m_opacity < other->m_opacity); } -void TextureMaterialWithOpacity::setTexture(const TextureReference *texture, bool opaque) +void TextureMaterialWithOpacity::setTexture(const QSGTextureRef &texture, bool opaque) { m_texture = texture; m_opaque = opaque; @@ -230,7 +230,7 @@ void TextureMaterialWithOpacityData::updateEffectState(Renderer *renderer, Abstr TextureMaterialWithOpacity *tx = static_cast<TextureMaterialWithOpacity *>(newEffect); TextureMaterialWithOpacity *oldTx = static_cast<TextureMaterialWithOpacity *>(oldEffect); - if (oldEffect == 0 || tx->texture() != oldTx->texture()) { + if (oldEffect == 0 || tx->texture().texture() != oldTx->texture().texture()) { renderer->setTexture(0, tx->texture()); oldEffect = 0; // Force filtering update. } diff --git a/src/scenegraph/convenience/texturematerial.h b/src/scenegraph/convenience/texturematerial.h index 5cce7ed..166bca1 100644 --- a/src/scenegraph/convenience/texturematerial.h +++ b/src/scenegraph/convenience/texturematerial.h @@ -55,8 +55,8 @@ public: virtual int compare(const AbstractEffect *other) const; // ### gunnar: opaque -> alpha, as "hasAlphaChannel()" is what we normally use - void setTexture(const TextureReference *texture, bool opaque = false); - const TextureReference *texture() const { return m_texture; } + void setTexture(const QSGTextureRef &texture, bool opaque = false); + const QSGTextureRef &texture() const { return m_texture; } void setLinearFiltering(bool linearFiltering) { m_linear_filtering = linearFiltering; } bool linearFiltering() const { return m_linear_filtering; } @@ -64,7 +64,7 @@ public: static bool is(const AbstractEffect *effect); protected: - const TextureReference *m_texture; + QSGTextureRef m_texture; bool m_opaque; bool m_linear_filtering; }; @@ -96,7 +96,7 @@ public: virtual AbstractEffectType *type() const; virtual AbstractEffectProgram *createProgram() const; virtual int compare(const AbstractEffect *other) const; - void setTexture(const TextureReference *texture, bool opaque = false); + void setTexture(const QSGTextureRef &texture, bool opaque = false); void setOpacity(qreal opacity); qreal opacity() const { return m_opacity; } diff --git a/src/scenegraph/coreapi/qsgcontext.cpp b/src/scenegraph/coreapi/qsgcontext.cpp index a4632bb..a2fe816 100644 --- a/src/scenegraph/coreapi/qsgcontext.cpp +++ b/src/scenegraph/coreapi/qsgcontext.cpp @@ -6,17 +6,18 @@ #include "default/default_rectanglenode.h" #include "default/default_texturenode.h" #include "default/default_glyphnode.h" -#include "threadedtexturemanager.h" + +#include "qsgtexturemanager.h" #include <QApplication> -#ifdef Q_WS_MAC -#include "mactexturemanager.h" -#endif +//#ifdef Q_WS_MAC +//#include "mactexturemanager.h" +//#endif -#ifdef Q_WS_QPA -#include "qsgeglfsthreadedtexturemanager.h" -#endif +//#ifdef Q_WS_QPA +//#include "qsgeglfsthreadedtexturemanager.h" +//#endif #include <private/qobject_p.h> @@ -32,7 +33,7 @@ public: RootNode *rootNode; Renderer *renderer; - TextureManager *textureManager; + QSGTextureManager *textureManager; QGLContext *gl; }; @@ -112,7 +113,7 @@ void QSGContext::initialize(QGLContext *context) texture manager is constructed through one call to createTextureManager() during the scene graph context's initialization */ -TextureManager *QSGContext::textureManager() const +QSGTextureManager *QSGContext::textureManager() const { Q_D(const QSGContext); return d->textureManager; @@ -167,28 +168,28 @@ Renderer *QSGContext::createRenderer() /*! Factory function for the texture manager to be used for this scene graph. */ -TextureManager *QSGContext::createTextureManager() +QSGTextureManager *QSGContext::createTextureManager() { QStringList args = qApp->arguments(); - if (args.contains("--basic-texture-manager")) { - printf("QSGContext: Using basic texture manager\n"); - return new TextureManager; - } else if (args.contains("--threaded-texture-manager")) { - printf("QSGContext: Using threaded texture manager\n"); - return new QSGThreadedTextureManager; - } - -#if defined (Q_WS_MAC) - printf("QSGContext:: Using Mac Texture manager\n"); - return new QSGMacTextureManager; -#elif defined (Q_WS_WIN) - printf("QSGContext:: Using Threaded Texture Manager\n"); - return new QSGThreadedTextureManager; -#elif defined (Q_WS_QPA) - printf("QSGContext:: Using EglFS Threaded Texture Manager\n"); - return new QSGEglFSThreadedTextureManager; -#endif - - return new TextureManager; +// if (args.contains("--basic-texture-manager")) { +// printf("QSGContext: Using basic texture manager\n"); + return new QSGTextureManager; +// } else if (args.contains("--threaded-texture-manager")) { +// printf("QSGContext: Using threaded texture manager\n"); +// return new QSGThreadedTextureManager; +// } + +//#if defined (Q_WS_MAC) +// printf("QSGContext:: Using Mac Texture manager\n"); +// return new QSGMacTextureManager; +//#elif defined (Q_WS_WIN) +// printf("QSGContext:: Using Threaded Texture Manager\n"); +// return new QSGThreadedTextureManager; +//#elif defined (Q_WS_QPA) +// printf("QSGContext:: Using EglFS Threaded Texture Manager\n"); +// return new QSGEglFSThreadedTextureManager; +//#endif + +// return new TextureManager; } diff --git a/src/scenegraph/coreapi/qsgcontext.h b/src/scenegraph/coreapi/qsgcontext.h index 01772ee..90f7451 100644 --- a/src/scenegraph/coreapi/qsgcontext.h +++ b/src/scenegraph/coreapi/qsgcontext.h @@ -13,7 +13,7 @@ class RectangleNodeInterface; class TextureNodeInterface; class GlyphNodeInterface; class Renderer; -class TextureManager; +class QSGTextureManager; class QT_SCENEGRAPH_EXPORT QSGContext : public QObject { @@ -27,7 +27,7 @@ public: Renderer *renderer() const; - TextureManager *textureManager() const; + QSGTextureManager *textureManager() const; void setRootNode(RootNode *node); RootNode *rootNode() const; @@ -42,7 +42,7 @@ public: virtual TextureNodeInterface *createTextureNode(); virtual GlyphNodeInterface *createGlyphNode(); virtual Renderer *createRenderer(); - virtual TextureManager *createTextureManager(); + virtual QSGTextureManager *createTextureManager(); signals: void ready(); diff --git a/src/scenegraph/coreapi/qsgtexturemanager.cpp b/src/scenegraph/coreapi/qsgtexturemanager.cpp new file mode 100644 index 0000000..d8ce090 --- /dev/null +++ b/src/scenegraph/coreapi/qsgtexturemanager.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** 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 Qt scene graph research project. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgtexturemanager.h" + +#include <QImage> + +#include <qgl.h> + +QSGTexture::QSGTexture() + : m_status(Null) + , m_texture_id(0) + , m_ref_count(0) + , m_has_alpha(false) + , m_owns_texture(true) + , m_has_mipmaps(false) +{ +} + + + +QSGTexture::~QSGTexture() +{ + if (m_owns_texture) + glDeleteTextures(1, (GLuint *) &m_texture_id); +} + + + +void QSGTexture::setStatus(Status s) +{ + m_status = s; + Q_ASSERT(s != Ready || (m_texture_id > 0 && !m_texture_size.isEmpty())); + emit statusChanged(s); +} + + + +QSGTextureManager::QSGTextureManager() +{ +} + + + +QImage QSGTextureManager::swizzleBGGRAToRGBA(const QImage &image) +{ + QImage img = image.copy(); + const int width = img.width(); + const int height = img.height(); + for (int i = 0; i < height; ++i) { + uint *p = (uint *) img.scanLine(i); + for (int x = 0; x < width; ++x) + p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00); + } + return img; +} + + + +QSGTextureRef QSGTextureManager::upload(const QImage &image) +{ + GLuint id; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + +#ifdef QT_OPENGL_ES + QImage i = swizzleBGRAToRGBA(image); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, i.width(), i.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, i.constBits()); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); +#endif + + QSGTexture *texture = new QSGTexture; + texture->setTextureId(id); + texture->setTextureSize(image.size()); + texture->setAlphaChannel(image.hasAlphaChannel()); + texture->setStatus(QSGTexture::Ready); + + QSGTextureRef ref(texture); + return ref; +} + + + +QSGTextureRef QSGTextureManager::requestUpload(const QImage &image, + const QObject *listener, + const char *slot) +{ + QSGTextureRef texture = upload(image); + return texture; +} + diff --git a/src/scenegraph/coreapi/qsgtexturemanager.h b/src/scenegraph/coreapi/qsgtexturemanager.h new file mode 100644 index 0000000..ef0c910 --- /dev/null +++ b/src/scenegraph/coreapi/qsgtexturemanager.h @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** 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 Qt scene graph research project. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGTEXTUREMANAGER_H +#define QSGTEXTUREMANAGER_H + +#include "qmlscene_global.h" + +#include <QObject> +#include <QImage> + +class QSGTextureManagerPrivate; + +class QT_SCENEGRAPH_EXPORT QSGTexture : public QObject +{ + Q_OBJECT + +public: + enum Status { + Null, + Loading, + Ready, + Error + }; + + QSGTexture(); + ~QSGTexture(); + + void setTextureId(int id) { m_texture_id = id; } + int textureId() const { return m_texture_id; } + + void setTextureSize(const QSize &size) { m_texture_size = size; } + QSize textureSize() const { return m_texture_size; } + + void setAlphaChannel(bool hasAlpha) { m_has_alpha = hasAlpha; } + bool hasAlphaChannel() const { return m_has_alpha; } + + void setOwnsTexture(bool does) { m_owns_texture = does; } + bool ownsTexture() const { return m_owns_texture; } + + void setHasMipmaps(bool has) { m_has_mipmaps = has; } + bool hasMipmaps() const { return m_has_mipmaps; } + + void setStatus(Status s); + Status status() const { return m_status; } + +signals: + void statusChanged(int status); + + // ### put into the private object... +public: + Status m_status; + int m_texture_id; + mutable int m_ref_count; + + QSize m_texture_size; + + uint m_has_alpha : 1; + uint m_owns_texture : 1; + uint m_has_mipmaps : 1; + + friend class QSGTextureRef; +}; + + +class QT_SCENEGRAPH_EXPORT QSGTextureRef +{ +public: + QSGTextureRef() + : m_texture(0) + { + } + + QSGTextureRef(const QSGTexture *texture, const QRectF &subrect = QRectF(0, 0, 1, 1)) + : m_texture(texture) + , m_sub_rect(subrect) + { + if (texture) + ++texture->m_ref_count; + } + + QSGTextureRef(const QSGTextureRef &other) + : m_sub_rect(other.m_sub_rect) + { + m_texture = other.m_texture; + ++m_texture->m_ref_count; + } + + ~QSGTextureRef() + { + deref(); + } + + void setSubRect(const QRectF &subrect) { m_sub_rect = subrect; } + QRectF subRect() const { return m_sub_rect; } + + const QSGTexture *texture() const { return m_texture; } + const QSGTexture *operator->() const { return m_texture; } + + QSGTextureRef &operator=(const QSGTextureRef &other) + { + ++other.m_texture->m_ref_count; + deref(); + m_texture = other.m_texture; + m_sub_rect = other.m_sub_rect; + + return *this; + } + + bool isNull() const { return m_texture == 0; } + +private: + void deref() { + if (m_texture && !--m_texture->m_ref_count) { + delete m_texture; + } + } + + const QSGTexture *m_texture; + QRectF m_sub_rect; +}; + + +class QT_SCENEGRAPH_EXPORT QSGTextureManager +{ +public: + QSGTextureManager(); + + virtual QSGTextureRef upload(const QImage &image); + virtual QSGTextureRef requestUpload(const QImage &image, const QObject *listener, const char *slot); + + static QImage swizzleBGGRAToRGBA(const QImage &image); + +private: + QSGTextureManagerPrivate *d; +}; + +#endif // QSGTEXTUREMANAGER_H diff --git a/src/scenegraph/coreapi/renderer.cpp b/src/scenegraph/coreapi/renderer.cpp index 1178b5a..8fa8da3 100644 --- a/src/scenegraph/coreapi/renderer.cpp +++ b/src/scenegraph/coreapi/renderer.cpp @@ -151,14 +151,14 @@ void Renderer::setClearColor(const QColor &color) m_clear_color = color; } -void Renderer::setTexture(int unit, const TextureReference *texture) +void Renderer::setTexture(int unit, const QSGTextureRef &texture) { if (unit < 0) return; // Select the texture unit and bind the texture. glActiveTexture(GL_TEXTURE0 + unit); - if (!texture) { + if (texture.isNull()) { glBindTexture(GL_TEXTURE_2D, 0); } else { glBindTexture(GL_TEXTURE_2D, texture->textureId()); diff --git a/src/scenegraph/coreapi/renderer.h b/src/scenegraph/coreapi/renderer.h index 2f80277..fc11a63 100644 --- a/src/scenegraph/coreapi/renderer.h +++ b/src/scenegraph/coreapi/renderer.h @@ -53,6 +53,7 @@ #include <qglshaderprogram.h> #include "node.h" +#include "qsgtexturemanager.h" class AbstractEffectProgram; struct AbstractEffectType; @@ -122,8 +123,8 @@ public: void setClearColor(const QColor &color); - void setTexture(int unit, const TextureReference *texture); - void setTexture(const TextureReference *texture) { setTexture(0, texture); } + void setTexture(int unit, const QSGTextureRef &texture); + void setTexture(const QSGTextureRef &texture) { setTexture(0, texture); } void renderScene(); void renderScene(const Bindable &bindable); diff --git a/src/scenegraph/scenegraph.pri b/src/scenegraph/scenegraph.pri index 80514c8..b48d8a4 100644 --- a/src/scenegraph/scenegraph.pri +++ b/src/scenegraph/scenegraph.pri @@ -9,6 +9,7 @@ HEADERS += $$PWD/coreapi/geometry.h \ $$PWD/coreapi/renderer.h \ $$PWD/coreapi/qmlrenderer.h \ $$PWD/coreapi/qsgcontext.h \ + scenegraph/coreapi/qsgtexturemanager.h SOURCES += $$PWD/coreapi/geometry.cpp \ $$PWD/coreapi/material.cpp \ @@ -16,7 +17,8 @@ SOURCES += $$PWD/coreapi/geometry.cpp \ $$PWD/coreapi/nodeupdater.cpp \ $$PWD/coreapi/renderer.cpp \ $$PWD/coreapi/qmlrenderer.cpp \ - $$PWD/coreapi/qsgcontext.h + $$PWD/coreapi/qsgcontext.h \ + scenegraph/coreapi/qsgtexturemanager.cpp # Convenience API |