diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-14 15:41:05 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-26 08:59:24 +0000 |
commit | 75f794dfd1f60e4baefcaa53993cd817798a1b3f (patch) | |
tree | 311226648932d3f615150c01eedaaf234656be6b /src | |
parent | d10007a2b15de7a530511968b4563164cb9e581b (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.cpp | 49 | ||||
-rw-r--r-- | src/core/delegated_frame_node.h | 2 |
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); |