From ac5a6f9ed06b98aa63981dd5d30e0febf36010d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Br=C3=BCning?= Date: Mon, 13 Feb 2017 16:54:24 +0100 Subject: 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 Reviewed-by: Allan Sandfeld Jensen --- src/core/delegated_frame_node.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'src/core/delegated_frame_node.cpp') 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(*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: { -- cgit v1.2.3