summaryrefslogtreecommitdiffstats
path: root/src/adaptationlayers/threadedtexturemanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/adaptationlayers/threadedtexturemanager.cpp')
-rw-r--r--src/adaptationlayers/threadedtexturemanager.cpp136
1 files changed, 92 insertions, 44 deletions
diff --git a/src/adaptationlayers/threadedtexturemanager.cpp b/src/adaptationlayers/threadedtexturemanager.cpp
index 616f0ec..665dbd9 100644
--- a/src/adaptationlayers/threadedtexturemanager.cpp
+++ b/src/adaptationlayers/threadedtexturemanager.cpp
@@ -24,29 +24,15 @@ struct TextureToUpload
class QSGTTMUploadThread : public QThread
{
public:
- QSGTTMUploadThread() {
- QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
- // Getting the share widget from the current context is rather nasty and
- // will not work for lighthouse based
- Q_ASSERT(ctx->device() && ctx->device()->devType() == QInternal::Widget);
-
- QGLWidget *share = static_cast<QGLWidget *>(ctx->device());
-
- widget = new QGLWidget(0, share);
- widget->resize(8, 8);
-
- context = const_cast<QGLContext *>(widget->context());
-
- widget->doneCurrent();
-
- ctx->makeCurrent();
-
+ QSGTTMUploadThread(QSGThreadedTextureManager *m)
+ : manager(m)
+ {
start();
}
void run() {
- context->makeCurrent();
+ manager->makeThreadContextCurrent();
while (true) {
@@ -66,49 +52,42 @@ public:
if (work.image.isNull())
continue;
-#ifdef QT_OPENGL_ES
- qWarning("ThreadedTextureManager: Chances are that BGRA does not work on GLES");
-#endif
-
- GLuint id;
- glGenTextures(1, &id);
- glBindTexture(GL_TEXTURE_2D, id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, work.image.width(), work.image.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, work.image.constBits());
-
- if (work.hints & TextureManager::GenerateMipmapUploadHint)
- glGenerateMipmap(GL_TEXTURE_2D);
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- work.texture->setTextureId(id);
- work.texture->setTextureSize(work.image.size());
- work.texture->setMipmaps(work.hints & TextureManager::GenerateMipmapUploadHint);
- work.texture->setStatus(TextureReference::Uploaded);
+ manager->uploadInThread(work.texture, work.image, work.hints);
}
}
- QGLWidget *widget;
- QGLContext *context;
+ QSGThreadedTextureManager *manager;
QWaitCondition condition;
QMutex mutex;
-
QQueue<TextureToUpload> requests;
+
+
};
class QSGThreadedTextureManagerPrivate
{
public:
- QSGTTMUploadThread thread;
+ QSGTTMUploadThread *thread;
+ QGLContext *context;
+ QGLWidget *widget;
};
QSGThreadedTextureManager::QSGThreadedTextureManager()
{
d = new QSGThreadedTextureManagerPrivate;
+ d->thread = 0;
+ d->context = 0;
+ d->widget = 0;
}
const TextureReference *QSGThreadedTextureManager::requestUploadedTexture(const QImage &image, UploadHints hints, QObject *listener, const char *slot)
{
+ if (!d->thread) {
+ d->thread = new QSGTTMUploadThread(this);
+ initializeThreadContext();
+ }
+
Q_ASSERT(!image.isNull());
if (hints & SynchronousUploadHint) {
@@ -122,15 +101,84 @@ const TextureReference *QSGThreadedTextureManager::requestUploadedTexture(const
QObject::connect(work.texture, SIGNAL(statusChanged(int)), listener, slot);
- d->thread.mutex.lock();
+ d->thread->mutex.lock();
- d->thread.requests << work;
- d->thread.condition.wakeOne();
- d->thread.mutex.unlock();
+ d->thread->requests << work;
+ d->thread->condition.wakeOne();
+ d->thread->mutex.unlock();
return work.texture;
}
+/*!
+ Reimplement this function to initialize a non-standard threaded context.
+
+ This function is called from the same thread as the scene graph is running
+ in. The default implementation will construct a QGLWidget, extract its
+ context and use this context in the background thread.
+ */
+void QSGThreadedTextureManager::initializeThreadContext()
+{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
+ // Getting the share widget from the current context is rather nasty and
+ // will not work for lighthouse based
+ Q_ASSERT(ctx->device() && ctx->device()->devType() == QInternal::Widget);
+
+ QGLWidget *share = static_cast<QGLWidget *>(ctx->device());
+
+ d->widget = new QGLWidget(0, share);
+ d->widget->resize(8, 8);
+
+ d->context = const_cast<QGLContext *>(d->widget->context());
+
+ d->widget->doneCurrent();
+
+ ctx->makeCurrent();
+}
+
+
+
+/*!
+ Reimplement this function to make the threaded context current.
+
+ This function is called from the background thread. The default
+ implementation makes the context created in initializeThreadContext
+ current.
+ */
+void QSGThreadedTextureManager::makeThreadContextCurrent()
+{
+ d->context->makeCurrent();
+}
+
+/*!
+ Reimplement this function to upload images in the background thread.
+
+ This function is called from the background thread. The default
+ implementation does this using a single glTexImage2D call.
+ */
+
+void QSGThreadedTextureManager::uploadInThread(TextureReference *texture, const QImage &image, UploadHints hints)
+{
+#ifdef QT_OPENGL_ES
+ qWarning("ThreadedTextureManager: Chances are that BGRA does not work on GLES");
+#endif
+
+ GLuint id;
+ glGenTextures(1, &id);
+ glBindTexture(GL_TEXTURE_2D, id);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
+
+ if (hints & TextureManager::GenerateMipmapUploadHint)
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ texture->setOwnsTexture(true);
+ texture->setTextureId(id);
+ texture->setTextureSize(image.size());
+ texture->setMipmaps(hints & TextureManager::GenerateMipmapUploadHint);
+ texture->setStatus(TextureReference::Uploaded);
+}