diff options
-rw-r--r-- | TODO | 7 | ||||
-rw-r--r-- | src/adaptationlayers/adaptationlayers.pri | 9 | ||||
-rw-r--r-- | src/adaptationlayers/mactexturemanager.cpp | 47 | ||||
-rw-r--r-- | src/adaptationlayers/mactexturemanager.h | 14 | ||||
-rw-r--r-- | src/adaptationlayers/threadedtexturemanager.cpp | 2 | ||||
-rw-r--r-- | src/graphicsitems/qximagebase.cpp | 4 | ||||
-rw-r--r-- | src/scenegraph/coreapi/qsgcontext.cpp | 8 | ||||
-rw-r--r-- | src/scenegraph/coreapi/renderer.cpp | 5 | ||||
-rw-r--r-- | tests/image-asynchronous.qml | 2 |
9 files changed, 93 insertions, 5 deletions
@@ -41,3 +41,10 @@ - Fix any reference to "// ### gunnar: port properly". Some of these will be pointless to port as the upgrade to new QML items is pretty close, so we'll have to evaluate those individually.. + +- Threaded texture uploads on Mac OS X seems pretty pointless. No matter what I try it seems + like I get a hit of 25 ms in the main thread even though shark tells me that a lot of effort + has been spent in the background thread too. From the shark traces it looks like the driver + does a texture memcpy for the first glDrawElements() that uses the texture in the UI thread. + I guess that only leaves PBO uploads, but that won't remedy the problem, I recon... + EDIT: CLIENT_STORAGE + TEXTURE_STORAGE as SHARED + seems to kill ALL performance problems diff --git a/src/adaptationlayers/adaptationlayers.pri b/src/adaptationlayers/adaptationlayers.pri index 514e32d..bbba835 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/adaptationlayers/threadedtexturemanager.h + $$PWD/threadedtexturemanager.h \ SOURCES += \ $$PWD/adaptationlayer.cpp \ @@ -14,4 +14,9 @@ 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 +} diff --git a/src/adaptationlayers/mactexturemanager.cpp b/src/adaptationlayers/mactexturemanager.cpp new file mode 100644 index 0000000..dec66c6 --- /dev/null +++ b/src/adaptationlayers/mactexturemanager.cpp @@ -0,0 +1,47 @@ +#include "mactexturemanager.h" + +/*! + Since we are using client storage which means asynchronous DMA + uploads, we need to keep the bits around for the duration + of the texture id. So we keep the image in along in the reference + */ +class QSGMacTextureReference : public TextureReference +{ +public: + QImage image; +}; + + +QSGMacTextureManager::QSGMacTextureManager() +{ +} + + +const TextureReference *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) + return TextureManager::requestUploadedTexture(image, hints, listener, slot); + + GLuint id; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + + glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, image.constBits()); + + glBindTexture(GL_TEXTURE_2D, 0); + + QSGMacTextureReference *texture = new QSGMacTextureReference; + texture->image = image; + texture->setTextureId(id); + texture->setTextureSize(image.size()); + texture->setStatus(TextureReference::Uploaded); + + return texture; +} diff --git a/src/adaptationlayers/mactexturemanager.h b/src/adaptationlayers/mactexturemanager.h new file mode 100644 index 0000000..89cba85 --- /dev/null +++ b/src/adaptationlayers/mactexturemanager.h @@ -0,0 +1,14 @@ +#ifndef MACTEXTUREMANAGER_H +#define MACTEXTUREMANAGER_H + +#include "adaptationlayer.h" + +class QT_SCENEGRAPH_EXPORT QSGMacTextureManager : public TextureManager +{ +public: + QSGMacTextureManager(); + + const TextureReference *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 2522733..4df4d6c 100644 --- a/src/adaptationlayers/threadedtexturemanager.cpp +++ b/src/adaptationlayers/threadedtexturemanager.cpp @@ -8,6 +8,7 @@ #include <QPaintDevice> #include <QGLWidget> +#include <qdatetime.h> struct TextureToUpload { @@ -114,6 +115,7 @@ const TextureReference *QSGThreadedTextureManager::requestUploadedTexture(const QObject::connect(work.texture, SIGNAL(statusChanged(int)), listener, slot); d->thread.mutex.lock(); + d->thread.requests << work; d->thread.condition.wakeOne(); d->thread.mutex.unlock(); diff --git a/src/graphicsitems/qximagebase.cpp b/src/graphicsitems/qximagebase.cpp index 8bbae28..e826f5c 100644 --- a/src/graphicsitems/qximagebase.cpp +++ b/src/graphicsitems/qximagebase.cpp @@ -203,8 +203,10 @@ void QxImageBase::requestFinished() 0, this, SLOT(textureStatusChanged(int))); - if (d->texture->status() == TextureReference::Uploaded) + + if (d->texture->status() == TextureReference::Uploaded) { pixmapChange(); + } } else { d->texture = tm->requestUploadedTexture(d->pix.pixmap().toImage(), TextureManager::SynchronousUploadHint); pixmapChange(); diff --git a/src/scenegraph/coreapi/qsgcontext.cpp b/src/scenegraph/coreapi/qsgcontext.cpp index 68a65bb..05eb477 100644 --- a/src/scenegraph/coreapi/qsgcontext.cpp +++ b/src/scenegraph/coreapi/qsgcontext.cpp @@ -8,6 +8,10 @@ #include "default/default_glyphnode.h" #include "threadedtexturemanager.h" +#ifdef Q_WS_MAC +#include "mactexturemanager.h" +#endif + #include <private/qobject_p.h> class QSGContextPrivate : public QObjectPrivate @@ -159,7 +163,9 @@ Renderer *QSGContext::createRenderer() */ TextureManager *QSGContext::createTextureManager() { -#if defined (Q_WS_MAC) || defined (Q_WS_WIN) +#if defined (Q_WS_MAC) + return new QSGMacTextureManager; +#elif defined (Q_WS_WIN) return new QSGThreadedTextureManager; #else return new TextureManager; diff --git a/src/scenegraph/coreapi/renderer.cpp b/src/scenegraph/coreapi/renderer.cpp index b666188..1178b5a 100644 --- a/src/scenegraph/coreapi/renderer.cpp +++ b/src/scenegraph/coreapi/renderer.cpp @@ -115,6 +115,9 @@ void Renderer::renderScene(const Bindable &bindable) if (!m_root_node) return; +// QTime time; +// time.start(); + preprocess(); bindable.bind(); GeometryDataUploader::bind(); @@ -122,6 +125,8 @@ void Renderer::renderScene(const Bindable &bindable) render(); GeometryDataUploader::release(); m_changed_emitted = false; + +// printf("rendering time: %d\n", time.elapsed()); } void Renderer::setProjectMatrixToDeviceRect() diff --git a/tests/image-asynchronous.qml b/tests/image-asynchronous.qml index 9212d18..d3d58f3 100644 --- a/tests/image-asynchronous.qml +++ b/tests/image-asynchronous.qml @@ -18,7 +18,7 @@ Rectangle { property int state: 0 Behavior on opacity { - NumberAnimation { duration: 250 } + NumberAnimation { duration: 500 } } |