summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@theqtcompany.com>2015-06-29 11:55:49 +0300
committerMiikka Heikkinen <miikka.heikkinen@theqtcompany.com>2015-06-29 10:59:37 +0000
commit44ed21d13964fc6aec0a13d0b82ccbbabd9aec86 (patch)
treef849790e868d489ab5bf5401fd07902acb2ce9fa
parent6526fd259530978e88b3365d7e95b57f60833799 (diff)
Make command queue size semi-dynamic
Command queue will now allocate more space if it runs out up until specified maximum size. This makes it to both consume less memory in most cases and behave better on background rendering cases that exceeded the old maximum size. Change-Id: I74d20b9bf7e2f028dd946b9348f0235b0e959682 Reviewed-by: Tomi Korpipää <tomi.korpipaa@theqtcompany.com> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@theqtcompany.com>
-rw-r--r--src/imports/qtcanvas3d/canvasrenderer.cpp11
-rw-r--r--src/imports/qtcanvas3d/glcommandqueue.cpp47
-rw-r--r--src/imports/qtcanvas3d/glcommandqueue_p.h7
3 files changed, 41 insertions, 24 deletions
diff --git a/src/imports/qtcanvas3d/canvasrenderer.cpp b/src/imports/qtcanvas3d/canvasrenderer.cpp
index a9e0420..377faf6 100644
--- a/src/imports/qtcanvas3d/canvasrenderer.cpp
+++ b/src/imports/qtcanvas3d/canvasrenderer.cpp
@@ -48,7 +48,8 @@
QT_BEGIN_NAMESPACE
QT_CANVAS3D_BEGIN_NAMESPACE
-const int commandQueueSize = 10000;
+const int initialQueueSize = 256;
+const int maxQueueSize = 1000000;
/*!
* \internal
@@ -73,7 +74,7 @@ CanvasRenderer::CanvasRenderer(QObject *parent):
m_displayFbo(0),
m_recreateFbos(false),
m_offscreenSurface(0),
- m_commandQueue(0), // command queue will be reset when context is created.
+ m_commandQueue(0, maxQueueSize), // command queue size will be reset when context is created.
m_executeQueue(0),
m_executeQueueCount(0),
m_executeStartIndex(0),
@@ -179,8 +180,8 @@ void CanvasRenderer::init(QQuickWindow *window, const CanvasContextAttributes &c
}
#endif
- m_commandQueue.resetQueue(commandQueueSize);
- m_executeQueue.resize(commandQueueSize);
+ m_commandQueue.resetQueue(initialQueueSize);
+ m_executeQueue.resize(initialQueueSize);
m_executeQueueCount = 0;
m_executeStartIndex = 0;
m_executeEndIndex = 0;
@@ -739,6 +740,8 @@ void CanvasRenderer::transferCommands()
{
if (m_glContext) {
const int count = m_commandQueue.queuedCount();
+ if (count > m_executeQueue.size())
+ m_executeQueue.resize(count);
if (m_renderTarget == Canvas::RenderTargetOffscreenBuffer) {
m_executeQueueCount = count;
m_commandQueue.transferCommands(m_executeQueue);
diff --git a/src/imports/qtcanvas3d/glcommandqueue.cpp b/src/imports/qtcanvas3d/glcommandqueue.cpp
index cef8150..5d18c82 100644
--- a/src/imports/qtcanvas3d/glcommandqueue.cpp
+++ b/src/imports/qtcanvas3d/glcommandqueue.cpp
@@ -55,16 +55,17 @@ QT_CANVAS3D_BEGIN_NAMESPACE
* The command data is copied for execution when GUI thread is blocked, so no extra synchronization
* is needed for that.
*/
-CanvasGlCommandQueue::CanvasGlCommandQueue(int size, QObject *parent) :
+CanvasGlCommandQueue::CanvasGlCommandQueue(int initialSize, int maxSize, QObject *parent) :
QObject(parent),
- m_maxSize(0),
+ m_maxSize(maxSize),
+ m_size(0),
m_queuedCount(0),
m_nextResourceId(1),
m_resourceIdOverflow(false),
m_clearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
{
- resetQueue(size);
+ resetQueue(initialSize);
}
CanvasGlCommandQueue::~CanvasGlCommandQueue()
@@ -79,21 +80,31 @@ CanvasGlCommandQueue::~CanvasGlCommandQueue()
* \internal
*
* Queues a new command \a id to the next available slot and returns a reference to that command,
- * so the caller can give it additional parameters.
+ * so the caller can give it additional parameters. If the queue is full, we simply reallocate some
+ * more space up to the max size.
*/
GlCommand &CanvasGlCommandQueue::queueCommand(CanvasGlCommandQueue::GlCommandId id)
{
- // If queue is full, we need to clear it first
- if (m_queuedCount == m_maxSize) {
- emit queueFull();
- // queueFull handling should reset the queue, but in case renderer thread is not available
- // to handle the commands for some reason, let's reset the count. In that case the entire
- // queue is lost, so results may not be pretty, but nothing much can be done about it.
- // Let's at least make sure we don't leak any memory.
- if (m_queuedCount) {
- deleteUntransferedCommandData();
- m_queuedCount = 0;
- clearQuickItemAsTextureList();
+ // Increase queue size if we run out of space. Note that this should only happen on the first
+ // frame on most applications, as we never decrease the allocated size.
+ if (m_queuedCount == m_size) {
+ // If queue is full and at max size, we need to synchronously execute all commands
+ if (m_queuedCount == m_maxSize) {
+ emit queueFull();
+ // queueFull handling should reset the queue, but in case renderer thread is not available
+ // to handle the commands for some reason, let's reset the count. In that case the entire
+ // queue is lost, so results may not be pretty, but nothing much can be done about it.
+ // Let's at least make sure we don't leak any memory.
+ if (m_queuedCount) {
+ deleteUntransferedCommandData();
+ m_queuedCount = 0;
+ clearQuickItemAsTextureList();
+ }
+ } else {
+ m_size += m_size / 2;
+ if (m_size > m_maxSize)
+ m_size = m_maxSize;
+ m_queue.resize(m_size);
}
}
@@ -212,10 +223,12 @@ void CanvasGlCommandQueue::resetQueue(int size)
clearQuickItemAsTextureList();
m_queuedCount = 0;
- m_maxSize = size;
+ m_size = size;
+ if (m_size > m_maxSize)
+ m_size = m_maxSize;
m_queue.clear();
- m_queue.resize(m_maxSize);
+ m_queue.resize(m_size);
m_resourceIdOverflow = false;
m_nextResourceId = 1;
diff --git a/src/imports/qtcanvas3d/glcommandqueue_p.h b/src/imports/qtcanvas3d/glcommandqueue_p.h
index 658df38..b5e8123 100644
--- a/src/imports/qtcanvas3d/glcommandqueue_p.h
+++ b/src/imports/qtcanvas3d/glcommandqueue_p.h
@@ -227,7 +227,7 @@ public:
};
- CanvasGlCommandQueue(int size = 10000, QObject *parent = 0);
+ CanvasGlCommandQueue(int initialSize, int maxSize, QObject *parent = 0);
~CanvasGlCommandQueue();
int queuedCount() const { return m_queuedCount; }
@@ -294,6 +294,7 @@ signals:
private:
QVector<GlCommand> m_queue;
int m_maxSize;
+ int m_size;
int m_queuedCount;
QMap<GLint, GlResource> m_resourceIdMap;
@@ -351,8 +352,6 @@ public:
data = 0;
}
- CanvasGlCommandQueue::GlCommandId id;
-
// Optional extra data such as buffer contents for commands that need it. The data is deleted
// after the command is handled. Not owned by command itself.
// Queue owns the data before it is transferred to execution, after which the CanvasRenderer
@@ -360,6 +359,8 @@ public:
// whoever owns the command object.
QByteArray *data;
+ CanvasGlCommandQueue::GlCommandId id;
+
GLint i1;
GLint i2;
GLint i3;