diff options
author | Gunnar Sletta <gunnar.sletta@jollamobile.com> | 2014-05-23 15:07:42 +0200 |
---|---|---|
committer | Gunnar Sletta <gunnar.sletta@jollamobile.com> | 2014-05-26 13:53:56 +0200 |
commit | 22095133d2af68f78d6905f215035f02a8933e68 (patch) | |
tree | 6e4c84783f722c7579aeb0e574de76249ad4e0c6 | |
parent | 488a8184b90801f3987779b5b1b046cf67ba0d4b (diff) |
Support eglgralloctextures through QQuickWindow::createTexture().
Change-Id: I8cbdfde5b47beb849327e4ae61c5009005ffc79c
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
-rw-r--r-- | customcontext/context.cpp | 20 | ||||
-rw-r--r-- | customcontext/context.h | 6 | ||||
-rw-r--r-- | customcontext/texture/eglgralloctexture.cpp | 60 | ||||
-rw-r--r-- | customcontext/texture/eglgralloctexture.h | 5 |
4 files changed, 71 insertions, 20 deletions
diff --git a/customcontext/context.cpp b/customcontext/context.cpp index 8b4ab6d..155bf54 100644 --- a/customcontext/context.cpp +++ b/customcontext/context.cpp @@ -424,6 +424,26 @@ QSGTexture *CONTEXT_CLASS::createTexture(const QImage &image) const return CONTEXT_CLASS_BASE::createTexture(image); } +#if QT_VERSION >= 0x050200 +QSGTexture *RenderContext::createTextureNoAtlas(const QImage &image) const +{ +#ifdef CUSTOMCONTEXT_EGLGRALLOCTEXTURE + if (static_cast<Context *>(sceneGraphContext())->hasEglGrallocTextures()) { + + // Only use gralloc textures for textures created outside the render thread. + // They can still block for as long as normal texture, so better to not waste + // the precious resource. + if (openglContext() != 0 && openglContext()->thread() != QThread::currentThread()) { + EglGrallocTexture *t = EglGrallocTexture::create(image); + if (t) + return t; + } + } +#endif + return CONTEXT_CLASS_BASE::createTextureNoAtlas(image); +} +#endif + QSGRenderer *CONTEXT_CLASS::createRenderer() diff --git a/customcontext/context.h b/customcontext/context.h index 830d854..962bd6b 100644 --- a/customcontext/context.h +++ b/customcontext/context.h @@ -76,6 +76,7 @@ public: void invalidate(); void renderNextFrame(QSGRenderer *renderer, GLuint fbo); QSGTexture *createTexture(const QImage &image) const; + QSGTexture *createTextureNoAtlas(const QImage &image) const; QSGRenderer *createRenderer(); #ifdef PROGRAM_BINARY @@ -134,6 +135,10 @@ public: QSGGlyphNode *createGlyphNode(); #endif +#ifdef CUSTOMCONTEXT_EGLGRALLOCTEXTURE + bool hasEglGrallocTextures() const { return m_eglGrallocTexture; } +#endif + private: int m_sampleCount; @@ -141,6 +146,7 @@ private: uint m_depthBuffer : 1; #if QT_VERSION < 0x50200 + friend class RenderContext; #ifdef CUSTOMCONTEXT_MATERIALPRELOAD bool m_materialPreloading; diff --git a/customcontext/texture/eglgralloctexture.cpp b/customcontext/texture/eglgralloctexture.cpp index 943f57d..fcf36c1 100644 --- a/customcontext/texture/eglgralloctexture.cpp +++ b/customcontext/texture/eglgralloctexture.cpp @@ -79,7 +79,7 @@ _glEGLImageTargetTexture2DOES glEGLImageTargetTexture2DOES = 0; _eglCreateImageKHR eglCreateImageKHR = 0; _eglDestroyImageKHR eglDestroyImageKHR = 0; -void initialize() +static void initialize() { hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **) &gralloc); gralloc_open((const hw_module_t *) gralloc, &alloc); @@ -215,10 +215,34 @@ void NativeBuffer::release() handle = 0; } +NativeBuffer *NativeBuffer::create(const QImage &image) +{ + if (image.width() * image.height() < 500 * 500) + return 0; + + if (gralloc == 0) { + initialize(); + if (!gralloc) + return 0; + } + + NativeBuffer *buffer = new NativeBuffer(image); + if (buffer && !buffer->handle) { +#ifdef CUSTOMCONTEXT_DEBUG + qDebug("EglGrallocTexture: failed to allocate native buffer for image: %d x %d", image.width(), image.height()); +#endif + delete buffer; + return 0; + } + + return buffer; +} + EglGrallocTexture::EglGrallocTexture(NativeBuffer *buffer) : m_id(0) , m_buffer(buffer) , m_bound(false) + , m_ownsBuffer(false) { Q_ASSERT(buffer); #ifdef CUSTOMCONTEXT_DEBUG @@ -230,6 +254,8 @@ EglGrallocTexture::~EglGrallocTexture() { if (m_id) glDeleteTextures(1, &m_id); + if (m_ownsBuffer) + delete m_buffer; } void EglGrallocTexture::bind() @@ -280,6 +306,16 @@ bool EglGrallocTexture::hasMipmaps() const return false; } +EglGrallocTexture *EglGrallocTexture::create(const QImage &image) +{ + NativeBuffer *buffer = NativeBuffer::create(image); + if (!buffer) + return 0; + EglGrallocTexture *texture = new EglGrallocTexture(buffer); + texture->m_ownsBuffer = true; + return texture; +} + EglGrallocTextureFactory::EglGrallocTextureFactory(NativeBuffer *buffer) : m_buffer(buffer) { @@ -293,7 +329,7 @@ EglGrallocTextureFactory::~EglGrallocTextureFactory() m_buffer->releaseEglImage(); } -QSGTexture *EglGrallocTextureFactory::createTexture(QQuickWindow *window) const +QSGTexture *EglGrallocTextureFactory::createTexture(QQuickWindow *) const { return new EglGrallocTexture(m_buffer); } @@ -330,24 +366,8 @@ QImage EglGrallocTextureFactory::image() const EglGrallocTextureFactory *EglGrallocTextureFactory::create(const QImage &image) { - if (image.width() * image.height() < 500 * 500) - return 0; - - if (gralloc == 0) { - initialize(); - if (!gralloc) - return 0; - } - - NativeBuffer *buffer = new NativeBuffer(image); - if (buffer && !buffer->handle) { -#ifdef CUSTOMCONTEXT_DEBUG - qDebug("EglGrallocTextureFactory: failed to allocate native buffer for image: %d x %d", image.width(), image.height()); -#endif - delete buffer; - return 0; - } - return new EglGrallocTextureFactory(buffer); + NativeBuffer *buffer = NativeBuffer::create(image); + return buffer ? new EglGrallocTextureFactory(buffer) : 0; } } diff --git a/customcontext/texture/eglgralloctexture.h b/customcontext/texture/eglgralloctexture.h index 2d05f7e..94d36b9 100644 --- a/customcontext/texture/eglgralloctexture.h +++ b/customcontext/texture/eglgralloctexture.h @@ -72,6 +72,8 @@ public: bool hasAlpha() const { return m_hasAlpha; } + static NativeBuffer *create(const QImage &image); + private: QAtomicInt m_ref; EGLImageKHR m_eglImage; @@ -91,10 +93,13 @@ public: virtual bool hasMipmaps() const; virtual void bind(); + static EglGrallocTexture *create(const QImage &image); + private: mutable GLuint m_id; NativeBuffer *m_buffer; bool m_bound; + bool m_ownsBuffer; }; class EglGrallocTextureFactory : public QQuickTextureFactory |