summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2010-12-07 22:44:32 +0100
committerGunnar Sletta <gunnar.sletta@nokia.com>2010-12-07 22:44:32 +0100
commitf5c4c7dff4b44dc80c117138229c0218bc22fbc3 (patch)
treebc002024efac4079bbf7decd3e13bab526e18efc
parentf3073afd4a44a659152a7983d55887090792b4a9 (diff)
Start yet another rewrite of the texture handling...
-rw-r--r--src/adaptationlayers/adaptationlayer.cpp172
-rw-r--r--src/adaptationlayers/adaptationlayer.h94
-rw-r--r--src/adaptationlayers/adaptationlayers.pri20
-rw-r--r--src/adaptationlayers/default/default_glyphnode_p.cpp15
-rw-r--r--src/adaptationlayers/default/default_glyphnode_p.h4
-rw-r--r--src/adaptationlayers/default/default_rectanglenode.cpp7
-rw-r--r--src/adaptationlayers/default/default_rectanglenode.h2
-rw-r--r--src/adaptationlayers/default/default_texturenode.cpp9
-rw-r--r--src/adaptationlayers/default/default_texturenode.h4
-rw-r--r--src/adaptationlayers/mactexturemanager.cpp2
-rw-r--r--src/adaptationlayers/mactexturemanager.h2
-rw-r--r--src/adaptationlayers/threadedtexturemanager.cpp2
-rw-r--r--src/adaptationlayers/threadedtexturemanager.h2
-rw-r--r--src/effects/shadereffectitem.cpp19
-rw-r--r--src/effects/shadereffectitem.h2
-rw-r--r--src/graphicsitems/nodes/qxninepatchnode.cpp4
-rw-r--r--src/graphicsitems/nodes/qxninepatchnode_p.h4
-rw-r--r--src/graphicsitems/qxborderimage.cpp5
-rw-r--r--src/graphicsitems/qxborderimage_p_p.h2
-rw-r--r--src/graphicsitems/qximagebase.cpp22
-rw-r--r--src/graphicsitems/qximagebase_p_p.h3
-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
30 files changed, 530 insertions, 272 deletions
diff --git a/src/adaptationlayers/adaptationlayer.cpp b/src/adaptationlayers/adaptationlayer.cpp
index fe31289..196891e 100644
--- a/src/adaptationlayers/adaptationlayer.cpp
+++ b/src/adaptationlayers/adaptationlayer.cpp
@@ -43,68 +43,110 @@
#include <qdatetime.h>
-/*!
- Constructs a new texture reference with status set to Null
- */
-TextureReference::TextureReference()
- : m_status(Null)
- , m_texture_id(0)
- , m_sub_rect(0, 0, 1, 1)
- , m_has_alpha(false)
- , m_owns_texture(false)
- , m_mipmap(false)
-{
-}
-
-TextureReference::~TextureReference()
-{
- if (m_owns_texture) {
- glDeleteTextures(1, (GLuint *) &m_texture_id);
- }
-}
-
-void TextureReference::setStatus(Status s)
-{
- m_status = s;
-
- Q_ASSERT(s != Uploaded || (m_texture_id > 0 && !m_texture_size.isEmpty()));
-
- emit statusChanged(s);
-}
-
-/*!
- Performs a synchronous upload of \a image using the specified \a hints.
-
- The upload is done using the QGLContext::bindTexture().
- */
-const TextureReference *TextureManager::requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot)
-{
- QTime time;
- time.start();
-
- QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
-
- QGLContext::BindOptions options = QGLContext::PremultipliedAlphaBindOption;
- if (hints & GenerateMipmapUploadHint)
- options |= QGLContext::MipmapBindOption;
-
- int id = context->bindTexture(image,
- GL_TEXTURE_2D,
- image.hasAlphaChannel() ? GL_RGBA : GL_RGB,
- options);
-
- printf("Texture uploaded in: %d\n", time.elapsed());
-
- TextureReference *ref = new TextureReference();
-
- if (listener && slot)
- QObject::connect(ref, SIGNAL(statusChanged(int)), listener, slot);
-
- ref->setTextureId(id);
- ref->setOwnsTexture(true);
- ref->setAlphaChannel(image.hasAlphaChannel());
- ref->setTextureSize(image.size());
- ref->setStatus(TextureReference::Uploaded);
-
- return ref;
-}
+///*!
+// Constructs a new texture reference with status set to Null
+// */
+//TextureReference::TextureReference()
+// : m_status(Null)
+// , m_texture_id(0)
+// , m_sub_rect(0, 0, 1, 1)
+// , m_has_alpha(false)
+// , m_mipmap(false)
+//{
+//}
+
+//TextureReference::~TextureReference()
+//{
+// if (m_owns_texture) {
+// glDeleteTextures(1, (GLuint *) &m_texture_id);
+// }
+//}
+
+//void TextureReference::setStatus(Status s)
+//{
+// m_status = s;
+
+// Q_ASSERT(s != Uploaded || (m_texture_id > 0 && !m_texture_size.isEmpty()));
+
+// emit statusChanged(s);
+//}
+
+//struct QSGTextureCacheKey {
+// quint64 cacheKey;
+// uint hints;
+//};
+
+//struct QSGTextureCacheEntry {
+// int ref;
+// GLuint id;
+//};
+
+//class QSGCachedTextureReference : public TextureReference
+//{
+//public:
+// ~QSGCachedTextureReference();
+
+// QSGTextureCacheEntry *entry;
+// TextureManagerPrivate *d;
+//};
+
+
+//uint qHash(const QSGTextureCacheKey &key)
+//{
+// return (key.cacheKey >> 32) ^ uint(key.cacheKey) ^ uint(key.hints);
+//}
+
+//class TextureManagerPrivate
+//{
+//public:
+// QHash<QSGTextureCacheKey, QSGTextureCacheEntry *> cache;
+//};
+
+//QSGCachedTextureReference::~QSGCachedTextureReference()
+//{
+// if (!--entry->ref) {
+// d->cache.remove(d->cache.key(entry));
+// glDeleteTextures(1, &entry->id);
+// delete entry;
+// }
+//}
+
+//const QSGTextureRef &TextureManager::requestUploadedTexture(const QImage &image,
+// UploadHints hints,
+// QObject *listener,
+// const char *slot)
+//{
+
+// QSGTextureCacheKey key = { image.cacheKey(), uint(hints) };
+// QSGTextureCacheEntry *entry = d->cache.value(key);
+
+// QSGCachedTextureReference *texture = new QSGCachedTextureReference();
+// QObject::connect(texture, SIGNAL(statusChanged(int)), listener, slot);
+// texture->setTextureSize(image.size());
+// texture->setAlphaChannel(image.hasAlphaChannel());
+// texture->setMipmaps(hints & GenerateMipmapUploadHint);
+
+// if (!entry) {
+// entry = new QSGTextureCacheEntry;
+// entry->id = uploadTexture(image, hints);
+// entry->ref = 1;
+// } else {
+// ++entry->ref;
+// // ### gunnar: this currently does not support the usecase where
+// // the same image is uploaded both as async and as sync...
+// texture->setStatus(TextureReference::Uploaded);
+// }
+
+// texture->setTextureId(entry->id);
+// texture->entry = entry;
+// return texture;
+//}
+
+///*!
+// Performs a synchronous upload of \a image using the specified \a hints.
+
+// The upload is done using the QGLContext::bindTexture().
+// */
+//GLuint TextureManager::uploadTexture(const QImage &image, UploadHints hints)
+//{
+//}
diff --git a/src/adaptationlayers/adaptationlayer.h b/src/adaptationlayers/adaptationlayer.h
index e43571b..eb2ca68 100644
--- a/src/adaptationlayers/adaptationlayer.h
+++ b/src/adaptationlayers/adaptationlayer.h
@@ -50,6 +50,7 @@
#include <QtCore/qurl.h>
#include "node.h"
+#include "qsgtexturemanager.h"
class Node;
class QImage;
@@ -108,8 +109,8 @@ public:
virtual void setOpacity(qreal opacity) = 0;
qreal opacity() const { return m_opacity; }
- virtual void setTexture(const TextureReference *ref) = 0;
- const TextureReference *texture() const;
+ virtual void setTexture(const QSGTextureRef &ref) = 0;
+ const QSGTextureRef &texture() const;
virtual void setClampToEdge(bool clampToEdge) = 0;
bool clampToEdge() const { return m_clamp_to_edge; }
@@ -118,7 +119,7 @@ public:
bool linearFiltering() const { return m_linear_filtering; }
protected:
- const TextureReference *m_texture;
+ QSGTextureRef m_texture;
QRectF m_rect;
QRectF m_source_rect;
qreal m_opacity;
@@ -127,83 +128,6 @@ protected:
};
-class TextureReference : public QObject
-{
- Q_OBJECT
-public:
- enum Status {
- Null,
- Uploaded,
- Uploading,
- Error
- };
-
- TextureReference();
- ~TextureReference();
-
- 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 setSubRect(const QRectF &subrect) { m_sub_rect = subrect; }
- QRectF subRect() const { return m_sub_rect; }
-
- void setAlphaChannel(bool hasAlpha) { m_has_alpha = hasAlpha; }
- bool hasAlphaChannel() const { return m_has_alpha; }
-
- void setOwnsTexture(bool owns) { m_owns_texture = owns; }
- bool ownsTexture() const { return m_owns_texture; }
-
- void setMipmaps(bool mipmapped) { m_mipmap = mipmapped; }
- bool hasMipmaps() const { return m_mipmap; }
-
- /*
- ### gunnar: the texture reference is potentially written to in a thread
- while uploading, so ANY access to the other accessors is strictly not
- allowed until status returns Uploaded.
- To support fetching and writing status from multiple threads, which I'm
- unsure if will happen, we should change status to be an QAtomicInt
- */
-
- void setStatus(Status s);
- Status status() const { return m_status; }
-
-signals:
- void statusChanged(int status);
-
-protected:
-
- Status m_status;
- int m_texture_id;
-
- QSize m_texture_size;
- QRectF m_sub_rect;
-
- uint m_has_alpha : 1;
- uint m_owns_texture : 1;
- uint m_mipmap : 1;
-};
-
-class TextureManager
-{
-public:
- enum UploadHint {
- SynchronousUploadHint = 0x0001,
- CanUseAtlasUploadHint = 0x0002,
-
- GenerateMipmapUploadHint = 0x0004,
-
- DefaultUploadHints = 0
- };
- Q_DECLARE_FLAGS(UploadHints, UploadHint);
-
- virtual ~TextureManager() { };
-
- virtual const TextureReference *requestUploadedTexture(const QImage &image, UploadHints hints = DefaultUploadHints, QObject *listener = 0, const char *slot = 0);
-};
-
//typedef QSharedPointer<const QGLTexture2D> QGLTexture2DConstPtr;
//typedef QSharedPointer<QGLTexture2D> QGLTexture2DPtr;
@@ -253,14 +177,4 @@ protected:
QColor m_color;
};
-class AdaptationLayerInterface
-{
-public:
- virtual RectangleNodeInterface *createRectangleNode() = 0;
- virtual TextureNodeInterface *createTextureNode() = 0;
- virtual GlyphNodeInterface *createGlyphNode() = 0;
- virtual Renderer *createRenderer() = 0;
- virtual TextureManager *textureManager() = 0;
-};
-
#endif
diff --git a/src/adaptationlayers/adaptationlayers.pri b/src/adaptationlayers/adaptationlayers.pri
index bd8743f..e28ddfd 100644
--- a/src/adaptationlayers/adaptationlayers.pri
+++ b/src/adaptationlayers/adaptationlayers.pri
@@ -6,7 +6,7 @@ HEADERS += \
$$PWD/default/default_rectanglenode.h \
$$PWD/default/default_glyphnode.h \
$$PWD/default/default_glyphnode_p.h \
- $$PWD/threadedtexturemanager.h
+# $$PWD/threadedtexturemanager.h
SOURCES += \
$$PWD/adaptationlayer.cpp \
@@ -14,15 +14,15 @@ SOURCES += \
$$PWD/default/default_rectanglenode.cpp \
$$PWD/default/default_glyphnode.cpp \
$$PWD/default/default_glyphnode_p.cpp \
- $$PWD/threadedtexturemanager.cpp
+# $$PWD/threadedtexturemanager.cpp
-macx:{
- SOURCES += adaptationlayers/mactexturemanager.cpp
- HEADERS += adaptationlayers/mactexturemanager.h
-}
+#macx:{
+# SOURCES += adaptationlayers/mactexturemanager.cpp
+# HEADERS += adaptationlayers/mactexturemanager.h
+#}
-contains(QT_CONFIG, qpa) {
- SOURCES += $$PWD/qsgeglfsthreadedtexturemanager.cpp
- HEADERS += $$PWD/qsgeglfsthreadedtexturemanager.h
-}
+#contains(QT_CONFIG, qpa) {
+# SOURCES += $$PWD/qsgeglfsthreadedtexturemanager.cpp
+# HEADERS += $$PWD/qsgeglfsthreadedtexturemanager.h
+#}
diff --git a/src/adaptationlayers/default/default_glyphnode_p.cpp b/src/adaptationlayers/default/default_glyphnode_p.cpp
index ffbfa7d..5db1a8b 100644
--- a/src/adaptationlayers/default/default_glyphnode_p.cpp
+++ b/src/adaptationlayers/default/default_glyphnode_p.cpp
@@ -132,9 +132,9 @@ void TextMaskMaterialData::updateEffectState(Renderer *renderer, AbstractEffect
}
bool updated = material->ensureUpToDate();
- Q_ASSERT(material->texture());
+ Q_ASSERT(!material->texture().isNull());
- Q_ASSERT(oldMaterial == 0 || oldMaterial->texture());
+ Q_ASSERT(oldMaterial == 0 || !oldMaterial->texture().isNull());
if (updated
|| oldMaterial == 0
|| oldMaterial->texture()->textureId() != material->texture()->textureId()) {
@@ -312,11 +312,12 @@ bool TextMaskMaterial::ensureUpToDate()
{
QSize glyphCacheSize(glyphCache()->width(), glyphCache()->height());
if (glyphCacheSize != m_size) {
- m_texture = new TextureReference;
- m_texture->setTextureId(glyphCache()->texture());
- m_texture->setTextureSize(QSize(glyphCache()->width(),
- glyphCache()->height()));
- m_texture->setStatus(TextureReference::Uploaded);
+ QSGTexture *t = new QSGTexture();
+ t->setTextureId(glyphCache()->texture());
+ t->setTextureSize(QSize(glyphCache()->width(), glyphCache()->height()));
+ t->setStatus(QSGTexture::Ready);
+ t->setOwnsTexture(false);
+ m_texture = QSGTextureRef(t);
m_size = glyphCacheSize;
diff --git a/src/adaptationlayers/default/default_glyphnode_p.h b/src/adaptationlayers/default/default_glyphnode_p.h
index 32907d0..6148ade 100644
--- a/src/adaptationlayers/default/default_glyphnode_p.h
+++ b/src/adaptationlayers/default/default_glyphnode_p.h
@@ -63,7 +63,7 @@ public:
void setColor(const QColor &color) { m_color = color; }
const QColor &color() const { return m_color; }
- TextureReference *texture() const { return m_texture; }
+ const QSGTextureRef &texture() const { return m_texture; }
void updateGlyphCache(const QGLContext *context);
@@ -83,7 +83,7 @@ public:
private:
void init();
- TextureReference *m_texture;
+ QSGTextureRef m_texture;
QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache;
QFontEngine *m_fontEngine;
QFontEngine *m_originalFontEngine;
diff --git a/src/adaptationlayers/default/default_rectanglenode.cpp b/src/adaptationlayers/default/default_rectanglenode.cpp
index 0412f2d..b6d5f26 100644
--- a/src/adaptationlayers/default/default_rectanglenode.cpp
+++ b/src/adaptationlayers/default/default_rectanglenode.cpp
@@ -147,7 +147,7 @@ void DefaultRectangleNode::setOpacity(qreal opacity)
if (opacity < 1) {
delete m_fill_material;
TextureMaterialWithOpacity *material = new TextureMaterialWithOpacity;
- if (m_gradient_texture)
+ if (!m_gradient_texture.isNull())
material->setTexture(m_gradient_texture, m_gradient_is_opaque);
material->setLinearFiltering(true);
material->setOpacity(opacity);
@@ -158,7 +158,7 @@ void DefaultRectangleNode::setOpacity(qreal opacity)
if (opacity >= 1) {
delete m_fill_material;
TextureMaterial *material = new TextureMaterial;
- if (m_gradient_texture)
+ if (!m_gradient_texture.isNull())
material->setTexture(m_gradient_texture, m_gradient_is_opaque);
material->setLinearFiltering(true);
m_fill_material = material;
@@ -679,8 +679,7 @@ void DefaultRectangleNode::updateGradientTexture()
line[i] = QColor::fromRgbF(c.redF() * c.alphaF(), c.greenF() * c.alphaF(), c.blueF() * c.alphaF(), c.alphaF()).rgba();
}
- m_gradient_texture = m_context->textureManager()->requestUploadedTexture(image,
- TextureManager::SynchronousUploadHint);
+ m_gradient_texture = m_context->textureManager()->upload(image);
Q_ASSERT(TextureMaterial::is(m_fill_material) || TextureMaterialWithOpacity::is(m_fill_material));
diff --git a/src/adaptationlayers/default/default_rectanglenode.h b/src/adaptationlayers/default/default_rectanglenode.h
index cd69fae..4cbaeac 100644
--- a/src/adaptationlayers/default/default_rectanglenode.h
+++ b/src/adaptationlayers/default/default_rectanglenode.h
@@ -85,7 +85,7 @@ private:
GeometryNode m_border;
AbstractEffect *m_fill_material; // Can be FlatColorMaterial, VertexColorMaterial, TextureMaterial or TextureMaterialWithOpacity.
FlatColorMaterial m_border_material;
- const TextureReference *m_gradient_texture;
+ QSGTextureRef m_gradient_texture;
bool m_gradient_is_opaque;
QSGContext *m_context;
diff --git a/src/adaptationlayers/default/default_texturenode.cpp b/src/adaptationlayers/default/default_texturenode.cpp
index 98aef05..5dcbba5 100644
--- a/src/adaptationlayers/default/default_texturenode.cpp
+++ b/src/adaptationlayers/default/default_texturenode.cpp
@@ -85,9 +85,10 @@ void DefaultTextureNode::setOpacity(qreal opacity)
setMaterial(opacity == 1 ? &m_material : &m_materialO); // Indicate that the material state has changed.
}
-void DefaultTextureNode::setTexture(const TextureReference *texture)
+void DefaultTextureNode::setTexture(const QSGTextureRef &texture)
{
- if (texture == m_texture)
+ if (texture.texture() == m_texture.texture()
+ && texture.subRect() == m_texture.subRect())
return;
m_texture = texture;
@@ -123,7 +124,7 @@ void DefaultTextureNode::update(uint updateFlags)
void DefaultTextureNode::updateGeometry()
{
- if (!m_texture)
+ if (m_texture.isNull())
return;
Geometry *g = geometry();
@@ -195,7 +196,7 @@ void DefaultTextureNode::updateGeometry()
qreal xSrcOffset = qFloor(normalizedSource.left());
qreal ySrcOffset = qFloor(normalizedSource.top());
- QRectF texSrcRect = m_texture->subRect();
+ QRectF texSrcRect = m_texture.subRect();
for (int j = 0; j < ySrc.size() - 1; ++j) {
for (int i = 0; i < xSrc.size() - 1; ++i) {
diff --git a/src/adaptationlayers/default/default_texturenode.h b/src/adaptationlayers/default/default_texturenode.h
index fb43ec3..4910681 100644
--- a/src/adaptationlayers/default/default_texturenode.h
+++ b/src/adaptationlayers/default/default_texturenode.h
@@ -55,7 +55,7 @@ public:
virtual void setRect(const QRectF &rect);
virtual void setSourceRect(const QRectF &rect);
virtual void setOpacity(qreal opacity);
- virtual void setTexture(const TextureReference *texture);
+ virtual void setTexture(const QSGTextureRef &texture);
virtual void setClampToEdge(bool clampToEdge);
virtual void setLinearFiltering(bool linearFiltering);
virtual void update(uint updateFlags);
@@ -69,7 +69,7 @@ private:
void updateGeometry();
void updateTexture();
- const TextureReference *m_texture;
+ QSGTextureRef m_texture;
TextureMaterial m_material;
TextureMaterialWithOpacity m_materialO;
};
diff --git a/src/adaptationlayers/mactexturemanager.cpp b/src/adaptationlayers/mactexturemanager.cpp
index 43d019d..0817727 100644
--- a/src/adaptationlayers/mactexturemanager.cpp
+++ b/src/adaptationlayers/mactexturemanager.cpp
@@ -30,7 +30,7 @@ QSGMacTextureManager::QSGMacTextureManager()
}
-const TextureReference *QSGMacTextureManager::requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot)
+const QSGTextureRef &QSGMacTextureManager::requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot)
{
// Client storage will most likely fail when mipmapping is used..
if (hints & TextureManager::GenerateMipmapUploadHint)
diff --git a/src/adaptationlayers/mactexturemanager.h b/src/adaptationlayers/mactexturemanager.h
index 89cba85..0560271 100644
--- a/src/adaptationlayers/mactexturemanager.h
+++ b/src/adaptationlayers/mactexturemanager.h
@@ -8,7 +8,7 @@ class QT_SCENEGRAPH_EXPORT QSGMacTextureManager : public TextureManager
public:
QSGMacTextureManager();
- const TextureReference *requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot);
+ const QSGTextureRef &requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot);
};
#endif // MACTEXTUREMANAGER_H
diff --git a/src/adaptationlayers/threadedtexturemanager.cpp b/src/adaptationlayers/threadedtexturemanager.cpp
index b9d128f..55aa414 100644
--- a/src/adaptationlayers/threadedtexturemanager.cpp
+++ b/src/adaptationlayers/threadedtexturemanager.cpp
@@ -81,7 +81,7 @@ QSGThreadedTextureManager::QSGThreadedTextureManager()
d->widget = 0;
}
-const TextureReference *QSGThreadedTextureManager::requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot)
+const QSGTextureRef &QSGThreadedTextureManager::requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot)
{
if (!d->thread) {
d->thread = new QSGTTMUploadThread(this);
diff --git a/src/adaptationlayers/threadedtexturemanager.h b/src/adaptationlayers/threadedtexturemanager.h
index 633f81c..36ec9f8 100644
--- a/src/adaptationlayers/threadedtexturemanager.h
+++ b/src/adaptationlayers/threadedtexturemanager.h
@@ -10,7 +10,7 @@ class QSGThreadedTextureManager : public TextureManager
public:
QSGThreadedTextureManager();
- const TextureReference *requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot);
+ const QSGTextureRef &requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot);
virtual void initializeThreadContext();
virtual void makeThreadContextCurrent();
diff --git a/src/effects/shadereffectitem.cpp b/src/effects/shadereffectitem.cpp
index 0826b8a..ed8ff93 100644
--- a/src/effects/shadereffectitem.cpp
+++ b/src/effects/shadereffectitem.cpp
@@ -261,11 +261,9 @@ void ShaderEffectSource::setMipmap(FilterMode mode)
Q_ASSERT(m_sourceItem);
delete m_fbo;
m_fbo = 0;
- } else if (m_texture) {
+ } else if (!m_texture.isNull()) {
Q_ASSERT(!m_sourceImage.isEmpty());
if (!m_texture->hasMipmaps()) {
- delete m_texture;
- m_texture = 0;
updateSizeAndTexture();
}
}
@@ -356,7 +354,7 @@ void ShaderEffectSource::bind() const
#endif
if (m_fbo) {
glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
- } else if (m_texture) {
+ } else if (!m_texture.isNull()) {
glBindTexture(GL_TEXTURE_2D, m_texture->textureId());
} else {
glBindTexture(GL_TEXTURE_2D, 0);
@@ -523,11 +521,14 @@ void ShaderEffectSource::updateSizeAndTexture()
m_size.setHeight(image.height());
emit heightChanged();
}
- TextureManager *tm = m_context->textureManager();
- TextureManager::UploadHints hints = TextureManager::SynchronousUploadHint;
- if (m_mipmap != None)
- hints |= TextureManager::GenerateMipmapUploadHint;
- m_texture = tm->requestUploadedTexture(image.mirrored(), hints);
+ QSGTextureManager *tm = m_context->textureManager();
+ m_texture = tm->upload(image.mirrored());
+
+ if (m_mipmap) {
+ glBindTexture(GL_TEXTURE_2D, m_texture->textureId());
+ glGenerateMipmap(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
} else {
if (m_size.width() != 0) {
diff --git a/src/effects/shadereffectitem.h b/src/effects/shadereffectitem.h
index bcdf220..a1db89a 100644
--- a/src/effects/shadereffectitem.h
+++ b/src/effects/shadereffectitem.h
@@ -166,7 +166,7 @@ private:
QSize m_size;
bool m_static;
- const TextureReference *m_texture;
+ QSGTextureRef m_texture;
QGLFramebufferObject *m_fbo;
QGLFramebufferObject *m_multisampledFbo;
Renderer *m_renderer;
diff --git a/src/graphicsitems/nodes/qxninepatchnode.cpp b/src/graphicsitems/nodes/qxninepatchnode.cpp
index 7dbc858..95b3971 100644
--- a/src/graphicsitems/nodes/qxninepatchnode.cpp
+++ b/src/graphicsitems/nodes/qxninepatchnode.cpp
@@ -43,7 +43,7 @@
#include "utilities.h"
#include "adaptationlayer.h"
-QxNinePatchNode::QxNinePatchNode(const QRectF &targetRect, const TextureReference *texture,
+QxNinePatchNode::QxNinePatchNode(const QRectF &targetRect, const QSGTextureRef &texture,
const QRect &innerRect, qreal opacity, bool linearFiltering)
: m_targetRect(targetRect), m_innerRect(innerRect), m_opacity(opacity), m_linearFiltering(linearFiltering)
{
@@ -137,7 +137,7 @@ void QxNinePatchNode::updateGeometry()
V *vertices = (V *)g->vertexData();
qreal x[6], y[6], u[6], v[6];
- QRectF texRect = m_texture->subRect();
+ QRectF texRect = m_texture.subRect();
x[0] = m_targetRect.x();
x[1] = m_targetRect.x() + m_innerRect.x();
diff --git a/src/graphicsitems/nodes/qxninepatchnode_p.h b/src/graphicsitems/nodes/qxninepatchnode_p.h
index 31d0a73..1759a8e 100644
--- a/src/graphicsitems/nodes/qxninepatchnode_p.h
+++ b/src/graphicsitems/nodes/qxninepatchnode_p.h
@@ -50,7 +50,7 @@ class TextureReference;
class QxNinePatchNode : public GeometryNode
{
public:
- QxNinePatchNode(const QRectF &targetRect, const TextureReference *texture, const QRect &innerRect, qreal opacity = 1., bool linearFiltering = false);
+ QxNinePatchNode(const QRectF &targetRect, const QSGTextureRef &texture, const QRect &innerRect, qreal opacity = 1., bool linearFiltering = false);
void setData(const QRectF &rect, qreal opacity);
@@ -71,7 +71,7 @@ private:
bool m_linearFiltering;
TextureMaterial m_material;
TextureMaterialWithOpacity m_materialO;
- const TextureReference *m_texture;
+ QSGTextureRef m_texture;
};
#if 0
diff --git a/src/graphicsitems/qxborderimage.cpp b/src/graphicsitems/qxborderimage.cpp
index 44e9411..fb4055a 100644
--- a/src/graphicsitems/qxborderimage.cpp
+++ b/src/graphicsitems/qxborderimage.cpp
@@ -339,10 +339,7 @@ void QxBorderImagePrivate::updatePixmap()
QRect inner(border->left(), border->top(), pix.width() - border->right() - border->left(),
pix.height() - border->bottom() - border->top());
- if (!texture) {
- texture = QSGContext::current->textureManager()->requestUploadedTexture(pix.pixmap().toImage(),
- TextureManager::SynchronousUploadHint);
- } // ### gunnar: does not support changing images...
+ texture = QSGContext::current->textureManager()->upload(pix.pixmap().toImage());
node = new QxNinePatchNode(QRectF(0, 0, q->width(), q->height()), texture, inner, q->renderOpacity(), smooth);
q->setPaintNode(node);
diff --git a/src/graphicsitems/qxborderimage_p_p.h b/src/graphicsitems/qxborderimage_p_p.h
index f5a9d33..933ca90 100644
--- a/src/graphicsitems/qxborderimage_p_p.h
+++ b/src/graphicsitems/qxborderimage_p_p.h
@@ -90,7 +90,7 @@ public:
void updateNode();
void updatePixmap();
QxNinePatchNode *node;
- const TextureReference *texture;
+ QSGTextureRef texture;
};
#endif // QXBORDERIMAGE_P_H
diff --git a/src/graphicsitems/qximagebase.cpp b/src/graphicsitems/qximagebase.cpp
index 416e242..21bf956 100644
--- a/src/graphicsitems/qximagebase.cpp
+++ b/src/graphicsitems/qximagebase.cpp
@@ -192,24 +192,18 @@ void QxImageBase::requestFinished()
emit progressChanged(d->progress);
- if (d->texture) {
- delete d->texture;
- d->texture = 0;
- }
-
- TextureManager *tm = QSGContext::current->textureManager();
+ QSGTextureManager *tm = QSGContext::current->textureManager();
if (d->async) {
- d->texture = tm->requestUploadedTexture(d->pix.pixmap().toImage(),
- 0,
- this,
- SLOT(textureStatusChanged(int)));
+ d->texture = tm->requestUpload(d->pix.pixmap().toImage(),
+ this,
+ SLOT(textureStatusChanged(int)));
- if (d->texture->status() == TextureReference::Uploaded) {
+ if (d->texture->status() == QSGTexture::Ready) {
pixmapChange();
}
} else {
- d->texture = tm->requestUploadedTexture(d->pix.pixmap().toImage(), TextureManager::SynchronousUploadHint);
+ d->texture = tm->upload(d->pix.pixmap().toImage());
pixmapChange();
}
}
@@ -218,12 +212,12 @@ void QxImageBase::textureStatusChanged(int status)
{
Q_D(QxImageBase);
- if (status == TextureReference::Uploaded) {
+ if (status == QSGTexture::Ready) {
d->status = Ready;
emit statusChanged(d->status);
}
- if (d->texture) {
+ if (!d->texture.isNull()) {
pixmapChange();
}
diff --git a/src/graphicsitems/qximagebase_p_p.h b/src/graphicsitems/qximagebase_p_p.h
index ab6b49b..6e28b8b 100644
--- a/src/graphicsitems/qximagebase_p_p.h
+++ b/src/graphicsitems/qximagebase_p_p.h
@@ -75,7 +75,6 @@ public:
~QxImageBasePrivate()
{
- delete texture;
}
QDeclarativePixmap pix;
@@ -83,7 +82,7 @@ public:
QUrl url;
qreal progress;
QSize sourcesize;
- const TextureReference *texture;
+ QSGTextureRef texture;
bool explicitSourceSize : 1;
bool async : 1;
};
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