summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@jollamobile.com>2014-05-23 15:07:42 +0200
committerGunnar Sletta <gunnar.sletta@jollamobile.com>2014-05-26 13:53:56 +0200
commit22095133d2af68f78d6905f215035f02a8933e68 (patch)
tree6e4c84783f722c7579aeb0e574de76249ad4e0c6
parent488a8184b90801f3987779b5b1b046cf67ba0d4b (diff)
Support eglgralloctextures through QQuickWindow::createTexture().
Change-Id: I8cbdfde5b47beb849327e4ae61c5009005ffc79c Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
-rw-r--r--customcontext/context.cpp20
-rw-r--r--customcontext/context.h6
-rw-r--r--customcontext/texture/eglgralloctexture.cpp60
-rw-r--r--customcontext/texture/eglgralloctexture.h5
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