summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-14 15:41:05 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-26 08:59:24 +0000
commit75f794dfd1f60e4baefcaa53993cd817798a1b3f (patch)
tree311226648932d3f615150c01eedaaf234656be6b /src
parentd10007a2b15de7a530511968b4563164cb9e581b (diff)
Reduce the amount of thread switches needed for fetching textures
Combine multiple texture fetches into a single sync call on another thread. Change-Id: Id372d5a11290105b36b34a4fc56bff9929304c20 Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io> Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/core/delegated_frame_node.cpp49
-rw-r--r--src/core/delegated_frame_node.h2
2 files changed, 44 insertions, 7 deletions
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index d6ee87950..78241a431 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -1263,6 +1263,8 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe
QList<gl::TransferableFence> transferredFences;
{
QMutexLocker lock(&m_mutex);
+ QVector<MailboxTexture *> mailboxesToPull;
+ mailboxesToPull.reserve(mailboxesToFetch.size());
gpu::SyncPointManager *syncPointManager = sync_point_manager();
base::MessageLoop *gpuMessageLoop = gpu_message_loop();
@@ -1271,9 +1273,12 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe
for (MailboxTexture *mailboxTexture : qAsConst(mailboxesToFetch)) {
gpu::SyncToken &syncToken = mailboxTexture->mailboxHolder().sync_token;
const auto task = base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture);
- if (syncPointManager->WaitOutOfOrderNonThreadSafe(syncToken, gpuMessageLoop->task_runner(), task))
- continue;
- gpuMessageLoop->task_runner()->PostTask(FROM_HERE, task);
+ if (!syncPointManager->WaitOutOfOrderNonThreadSafe(syncToken, gpuMessageLoop->task_runner(), std::move(task)))
+ mailboxesToPull.append(mailboxTexture);
+ }
+ if (!mailboxesToPull.isEmpty()) {
+ auto task = base::BindOnce(&DelegatedFrameNode::pullTextures, this, std::move(mailboxesToPull));
+ gpuMessageLoop->task_runner()->PostTask(FROM_HERE, std::move(task));
}
m_mailboxesFetchedWaitCond.wait(&m_mutex);
@@ -1349,6 +1354,25 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe
}
+void DelegatedFrameNode::pullTextures(DelegatedFrameNode *frameNode, const QVector<MailboxTexture *> textures)
+{
+#ifndef QT_NO_OPENGL
+ gpu::gles2::MailboxManager *mailboxManager = mailbox_manager();
+ for (MailboxTexture *texture : textures) {
+ gpu::SyncToken &syncToken = texture->mailboxHolder().sync_token;
+ if (syncToken.HasData())
+ mailboxManager->PullTextureUpdates(syncToken);
+ texture->fetchTexture(mailboxManager);
+ --frameNode->m_numPendingSyncPoints;
+ }
+
+ fenceAndUnlockQt(frameNode);
+#else
+ Q_UNUSED(frameNode)
+ Q_UNUSED(textures)
+#endif
+}
+
void DelegatedFrameNode::pullTexture(DelegatedFrameNode *frameNode, MailboxTexture *texture)
{
#ifndef QT_NO_OPENGL
@@ -1357,6 +1381,18 @@ void DelegatedFrameNode::pullTexture(DelegatedFrameNode *frameNode, MailboxTextu
if (syncToken.HasData())
mailboxManager->PullTextureUpdates(syncToken);
texture->fetchTexture(mailboxManager);
+ --frameNode->m_numPendingSyncPoints;
+
+ fenceAndUnlockQt(frameNode);
+#else
+ Q_UNUSED(frameNode)
+ Q_UNUSED(texture)
+#endif
+}
+
+void DelegatedFrameNode::fenceAndUnlockQt(DelegatedFrameNode *frameNode)
+{
+#ifndef QT_NO_OPENGL
if (!!gl::GLContext::GetCurrent() && gl::GLFence::IsSupported()) {
// Create a fence on the Chromium GPU-thread and context
gl::GLFence *fence = gl::GLFence::Create();
@@ -1364,15 +1400,14 @@ void DelegatedFrameNode::pullTexture(DelegatedFrameNode *frameNode, MailboxTextu
frameNode->m_textureFences.append(fence->Transfer());
delete fence;
}
- if (--frameNode->m_numPendingSyncPoints == 0)
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::fenceAndUnlockQt, frameNode));
+ if (frameNode->m_numPendingSyncPoints == 0)
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::unlockQt, frameNode));
#else
Q_UNUSED(frameNode)
- Q_UNUSED(texture)
#endif
}
-void DelegatedFrameNode::fenceAndUnlockQt(DelegatedFrameNode *frameNode)
+void DelegatedFrameNode::unlockQt(DelegatedFrameNode *frameNode)
{
QMutexLocker lock(&frameNode->m_mutex);
// Signal preprocess() the textures are ready
diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h
index c627cdf95..4bddf4a62 100644
--- a/src/core/delegated_frame_node.h
+++ b/src/core/delegated_frame_node.h
@@ -123,7 +123,9 @@ private:
// Making those callbacks static bypasses base::Bind's ref-counting requirement
// of the this pointer when the callback is a method.
static void pullTexture(DelegatedFrameNode *frameNode, MailboxTexture *mailbox);
+ static void pullTextures(DelegatedFrameNode *frameNode, const QVector<MailboxTexture *> mailboxes);
static void fenceAndUnlockQt(DelegatedFrameNode *frameNode);
+ static void unlockQt(DelegatedFrameNode *frameNode);
ResourceHolder *findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates);
void holdResources(const cc::DrawQuad *quad, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates);