summaryrefslogtreecommitdiffstats
path: root/src/scenegraph
diff options
context:
space:
mode:
Diffstat (limited to 'src/scenegraph')
-rw-r--r--src/scenegraph/convenience/texturematerial.cpp12
-rw-r--r--src/scenegraph/convenience/texturematerial.h8
-rw-r--r--src/scenegraph/coreapi/qsgcontext.cpp61
-rw-r--r--src/scenegraph/coreapi/qsgcontext.h6
-rw-r--r--src/scenegraph/coreapi/qsgtexturemanager.cpp130
-rw-r--r--src/scenegraph/coreapi/qsgtexturemanager.h176
-rw-r--r--src/scenegraph/coreapi/renderer.cpp4
-rw-r--r--src/scenegraph/coreapi/renderer.h5
-rw-r--r--src/scenegraph/scenegraph.pri4
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