From f5c4c7dff4b44dc80c117138229c0218bc22fbc3 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 7 Dec 2010 22:44:32 +0100 Subject: Start yet another rewrite of the texture handling... --- src/adaptationlayers/adaptationlayer.cpp | 172 ++++++++++++-------- src/adaptationlayers/adaptationlayer.h | 94 +---------- src/adaptationlayers/adaptationlayers.pri | 20 +-- .../default/default_glyphnode_p.cpp | 15 +- src/adaptationlayers/default/default_glyphnode_p.h | 4 +- .../default/default_rectanglenode.cpp | 7 +- .../default/default_rectanglenode.h | 2 +- .../default/default_texturenode.cpp | 9 +- src/adaptationlayers/default/default_texturenode.h | 4 +- src/adaptationlayers/mactexturemanager.cpp | 2 +- src/adaptationlayers/mactexturemanager.h | 2 +- src/adaptationlayers/threadedtexturemanager.cpp | 2 +- src/adaptationlayers/threadedtexturemanager.h | 2 +- src/effects/shadereffectitem.cpp | 19 +-- src/effects/shadereffectitem.h | 2 +- src/graphicsitems/nodes/qxninepatchnode.cpp | 4 +- src/graphicsitems/nodes/qxninepatchnode_p.h | 4 +- src/graphicsitems/qxborderimage.cpp | 5 +- src/graphicsitems/qxborderimage_p_p.h | 2 +- src/graphicsitems/qximagebase.cpp | 22 +-- src/graphicsitems/qximagebase_p_p.h | 3 +- src/scenegraph/convenience/texturematerial.cpp | 12 +- src/scenegraph/convenience/texturematerial.h | 8 +- src/scenegraph/coreapi/qsgcontext.cpp | 61 +++---- src/scenegraph/coreapi/qsgcontext.h | 6 +- src/scenegraph/coreapi/qsgtexturemanager.cpp | 130 +++++++++++++++ src/scenegraph/coreapi/qsgtexturemanager.h | 176 +++++++++++++++++++++ src/scenegraph/coreapi/renderer.cpp | 4 +- src/scenegraph/coreapi/renderer.h | 5 +- src/scenegraph/scenegraph.pri | 4 +- 30 files changed, 530 insertions(+), 272 deletions(-) create mode 100644 src/scenegraph/coreapi/qsgtexturemanager.cpp create mode 100644 src/scenegraph/coreapi/qsgtexturemanager.h 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 -/*! - 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::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 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 #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 QGLTexture2DConstPtr; //typedef QSharedPointer 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 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(newEffect); TextureMaterial *oldTx = static_cast(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(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(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(newEffect); TextureMaterialWithOpacity *oldTx = static_cast(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 -#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 @@ -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 + +#include + +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 +#include + +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 #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 -- cgit v1.2.3