summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJüri Valdmann <juri.valdmann@qt.io>2017-10-25 14:46:53 +0200
committerJüri Valdmann <juri.valdmann@qt.io>2017-10-26 11:39:02 +0000
commit3938260c7dcceee5cbf184d497b3b72d8b7a4910 (patch)
tree3ac95a8978b976244c3f6b874ea4de5471f2aec1
parent4649f2a11fe4b87e9b79f50ff8ac99ba9a2344f4 (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>
-rw-r--r--src/core/delegated_frame_node.cpp22
-rw-r--r--src/core/delegated_frame_node.h2
2 files changed, 22 insertions, 2 deletions
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index 73e0420a..7547e24f 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 3b6453a4..e87b6abe 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;