diff options
author | Jüri Valdmann <juri.valdmann@qt.io> | 2017-10-25 14:46:53 +0200 |
---|---|---|
committer | Jüri Valdmann <juri.valdmann@qt.io> | 2017-10-26 11:39:02 +0000 |
commit | 3938260c7dcceee5cbf184d497b3b72d8b7a4910 (patch) | |
tree | 3ac95a8978b976244c3f6b874ea4de5471f2aec1 /src | |
parent | 4649f2a11fe4b87e9b79f50ff8ac99ba9a2344f4 (diff) |
Fix overeager freeing of resources in DelegatedFrameNode
After every run of DelegatedFrameNode::commit we take all the resources we
didn't need and queue them for freeing. Problems appear however with the recent
change that introduced clipping of invisible render passes and draw quads as we
may now decide to release resources too early and eventually crash.
Task-number: QTBUG-64032
Change-Id: I95138bc4c1caf8c191bfc801264309c5b03ef0f3
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/delegated_frame_node.cpp | 22 | ||||
-rw-r--r-- | src/core/delegated_frame_node.h | 2 |
2 files changed, 22 insertions, 2 deletions
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index 73e0420af..7547e24f7 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -957,8 +957,10 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, scissorRect += rootRenderPass->output_rect.OffsetFromOrigin(); } - if (scissorRect.IsEmpty()) + if (scissorRect.IsEmpty()) { + holdResources(pass, resourceCandidates); continue; + } QSGNode *renderPassChain = nullptr; if (buildNewTree) @@ -981,8 +983,10 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, if (quadState->is_clipped) targetRect.Intersect(quadState->clip_rect); targetRect.Intersect(scissorRect); - if (targetRect.IsEmpty()) + if (targetRect.IsEmpty()) { + holdResources(quad, resourceCandidates); continue; + } if (quadState->sorting_context_id != currentSortingContextId) { flushPolygons(&polygonQueue, renderPassChain, @@ -1240,6 +1244,20 @@ ResourceHolder *DelegatedFrameNode::findAndHoldResource(unsigned resourceId, QHa return resource.data(); } +void DelegatedFrameNode::holdResources(const cc::DrawQuad *quad, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates) +{ + auto first = quad->resources.const_begin(); + auto last = quad->resources.const_end(); + for (auto it = first; it != last; ++it) + findAndHoldResource(*it, candidates); +} + +void DelegatedFrameNode::holdResources(const cc::RenderPass *pass, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates) +{ + for (const auto &quad : pass->quad_list) + holdResources(quad, candidates); +} + QSGTexture *DelegatedFrameNode::initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate) { // QSGTextures must be destroyed in the scene graph thread as part of the QSGNode tree, diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h index 3b6453a4c..e87b6abe3 100644 --- a/src/core/delegated_frame_node.h +++ b/src/core/delegated_frame_node.h @@ -125,6 +125,8 @@ private: static void fenceAndUnlockQt(DelegatedFrameNode *frameNode); ResourceHolder *findAndHoldResource(unsigned resourceId, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates); + void holdResources(const cc::DrawQuad *quad, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates); + void holdResources(const cc::RenderPass *pass, QHash<unsigned, QSharedPointer<ResourceHolder> > &candidates); QSGTexture *initAndHoldTexture(ResourceHolder *resource, bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0); QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData; |