diff options
author | Michael BrĂ¼ning <michael.bruning@qt.io> | 2017-02-13 16:54:24 +0100 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2017-02-15 09:46:39 +0000 |
commit | ac5a6f9ed06b98aa63981dd5d30e0febf36010d8 (patch) | |
tree | 152b4203c15a1046981fcb927af3c03ca8e9f86d /src/core | |
parent | 5f8e4afbba49c49d6e81b02d74505effc7b949ec (diff) |
Fix crashes in removeFromCanvas
After reparenting the view, the compositor data may still be the
same, but the node might be a different one. Check if the list of
scene graph nodes is empty when making the decision on whether to
build a new node tree or not. Also advance the node iterator for
missing render passes.
Task-number: QTBUG-58472
Change-Id: I28dfb40bda89470c7cdaec0aef8a976e307f5b6a
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/delegated_frame_node.cpp | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index 192109c6d..07b4bb2b6 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -216,6 +216,13 @@ public: void setupRenderPassNode(QSGTexture *layer, const QRect &rect, QSGNode *) Q_DECL_OVERRIDE { QSGInternalImageNode *imageNode = static_cast<QSGInternalImageNode*>(*m_nodeIterator++); + // In case of a missing render pass, set the target rects to be empty and return early. + // cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes + if (!layer) { + imageNode->setTargetRect(QRect()); + imageNode->setInnerTargetRect(QRect()); + return; + } imageNode->setTargetRect(rect); imageNode->setInnerTargetRect(rect); imageNode->setTexture(layer); @@ -305,13 +312,21 @@ public: { // Only QSGInternalImageNode currently supports QSGLayer textures. QSGInternalImageNode *imageNode = m_apiDelegate->createImageNode(); + layerChain->appendChildNode(imageNode); + m_sceneGraphNodes->append(imageNode); + + // In case of a missing render pass, set the target rects to be empty and return early. + // cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes + if (!layer) { + imageNode->setTargetRect(QRect()); + imageNode->setInnerTargetRect(QRect()); + return; + } + imageNode->setTargetRect(rect); imageNode->setInnerTargetRect(rect); imageNode->setTexture(layer); imageNode->update(); - - layerChain->appendChildNode(imageNode); - m_sceneGraphNodes->append(imageNode); } void setupTextureContentNode(QSGTexture *texture, const QRect &rect, @@ -850,7 +865,7 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, // equivalent to the render passes in the current frame data. If they are, we are going // to reuse the old nodes. Otherwise, we will delete the old nodes and build a new tree. cc::DelegatedFrameData *previousFrameData = m_chromiumCompositorData->previousFrameData.get(); - const bool buildNewTree = !areRenderPassStructuresEqual(frameData, previousFrameData); + const bool buildNewTree = !areRenderPassStructuresEqual(frameData, previousFrameData) || m_sceneGraphNodes.empty(); m_chromiumCompositorData->previousFrameData = nullptr; SGObjects previousSGObjects; @@ -931,9 +946,6 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, QSGTexture *layer = findRenderPassLayer(renderPassQuad->render_pass_id, m_sgObjects.renderPassLayers).data(); - // cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes. - if (!layer) - continue; nodeHandler->setupRenderPassNode(layer, toQt(quad->rect), currentLayerChain); break; } case cc::DrawQuad::TEXTURE_CONTENT: { |