aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-01-18 16:52:14 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-01-19 13:46:59 +0000
commitbe3ab3275539864db5989692e38dfb21571853b7 (patch)
treebbf38ee57e2b51ca9e183f195be224afc90b2c28 /src/quick/scenegraph
parent1381aff5850dbcb53de8b62a90f0c87cba1bb765 (diff)
Revert "Set the stencil buffer zone" and "Add clipNext null pointer guard"
This reverts commit 576d3fc2c84f324c035aa924c386f0615002fa16. This reverts commit 6382ec9a6c961f2b7d7139659c11a047f6b68b07. The original patch is broken in multiple ways: - Any at least two level deep clip where rotation is involved results in a failing assertion (triggers in debug builds only). - The assertion looks legit: using calculations meant only for 90, 180, 270 degree rootations for arbitrary rotations seems wrong. Taking frame captures with RenderDoc show that the generated scissor rectangle that is set before the glClear for the stencil buffer is _not_ correct, i.e. it does not correctly cover all the area that will be touched in the stencil buffer in the following draw call. - The logic for accessing the clip list is dubious. Hence a suspicion that the patch is not correct when it comes to the handling of the clip list: It is not clear why accessing clip->clipList()->matrix() is correct when the clip list is more than 2 levels deep. At the same time a single clipping item will not trigger the assertion because it does not set the scissor before the clear at all (which is contrary to what the patch is aiming to achieve). The original patch has a follow-up crash fix that is incorrect in its own right: it adds a null check for clipNext (i.e. the clip->clipList() mentioned above), while including code in the true branch that should execute regardless. Fixes: QTBUG-89898 Task-number: QTBUG-83108 Change-Id: Ic28bd8670a7663fd6232aaf5739b05fd16d2da24 Reviewed-by: Dominik Holland <dominik.holland@qt.io> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp44
1 files changed, 9 insertions, 35 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 3b49b88182..73c02d793b 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -2432,18 +2432,20 @@ ClipState::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
// TODO: Check for multisampling and pixel grid alignment.
bool isRectangleWithNoPerspective = clip->isRectangular()
&& qFuzzyIsNull(m(3, 0)) && qFuzzyIsNull(m(3, 1));
- auto noRotate = [] (const QMatrix4x4 &m) { return qFuzzyIsNull(m(0, 1)) && qFuzzyIsNull(m(1, 0)); };
- auto isRotate90 = [] (const QMatrix4x4 &m) { return qFuzzyIsNull(m(0, 0)) && qFuzzyIsNull(m(1, 1)); };
- auto scissorRect = [&] (const QRectF &bbox, const QMatrix4x4 &m) {
+ bool noRotate = qFuzzyIsNull(m(0, 1)) && qFuzzyIsNull(m(1, 0));
+ bool isRotate90 = qFuzzyIsNull(m(0, 0)) && qFuzzyIsNull(m(1, 1));
+
+ if (isRectangleWithNoPerspective && (noRotate || isRotate90)) {
+ QRectF bbox = clip->clipRect();
qreal invW = 1 / m(3, 3);
qreal fx1, fy1, fx2, fy2;
- if (noRotate(m)) {
+ if (noRotate) {
fx1 = (bbox.left() * m(0, 0) + m(0, 3)) * invW;
fy1 = (bbox.bottom() * m(1, 1) + m(1, 3)) * invW;
fx2 = (bbox.right() * m(0, 0) + m(0, 3)) * invW;
fy2 = (bbox.top() * m(1, 1) + m(1, 3)) * invW;
} else {
- Q_ASSERT(isRotate90(m));
+ Q_ASSERT(isRotate90);
fx1 = (bbox.bottom() * m(0, 1) + m(0, 3)) * invW;
fy1 = (bbox.left() * m(1, 0) + m(1, 3)) * invW;
fx2 = (bbox.top() * m(0, 1) + m(0, 3)) * invW;
@@ -2462,18 +2464,12 @@ ClipState::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
GLint ix2 = qRound((fx2 + 1) * deviceRect.width() * qreal(0.5));
GLint iy2 = qRound((fy2 + 1) * deviceRect.height() * qreal(0.5));
- return QRect(ix1, iy1, ix2 - ix1, iy2 - iy1);
- };
-
- if (isRectangleWithNoPerspective && (noRotate(m) || isRotate90(m))) {
- auto rect = scissorRect(clip->clipRect(), m);
-
if (!(clipType & ClipState::ScissorClip)) {
- m_currentScissorRect = rect;
+ m_currentScissorRect = QRect(ix1, iy1, ix2 - ix1, iy2 - iy1);
glEnable(GL_SCISSOR_TEST);
clipType |= ClipState::ScissorClip;
} else {
- m_currentScissorRect &= rect;
+ m_currentScissorRect &= QRect(ix1, iy1, ix2 - ix1, iy2 - iy1);
}
glScissor(m_currentScissorRect.x(), m_currentScissorRect.y(),
m_currentScissorRect.width(), m_currentScissorRect.height());
@@ -2488,31 +2484,9 @@ ClipState::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
m_clipProgram.link();
m_clipMatrixId = m_clipProgram.uniformLocation("matrix");
}
- const QSGClipNode *clipNext = clip->clipList();
- if (clipNext) {
- QMatrix4x4 mNext = m_current_projection_matrix;
- if (clipNext->matrix())
- mNext *= *clipNext->matrix();
-
- auto rect = scissorRect(clipNext->clipRect(), mNext);
-
- ClipState::ClipType clipTypeNext = clipType ;
- clipTypeNext |= ClipState::StencilClip;
- QRect m_next_scissor_rect = m_currentScissorRect;
- if (!(clipTypeNext & ClipState::ScissorClip)) {
- m_next_scissor_rect = rect;
- glEnable(GL_SCISSOR_TEST);
- } else {
- m_next_scissor_rect =
- m_currentScissorRect & rect;
- }
- glScissor(m_next_scissor_rect.x(), m_next_scissor_rect.y(),
- m_next_scissor_rect.width(), m_next_scissor_rect.height());
- }
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
- glDisable(GL_SCISSOR_TEST);
glEnable(GL_STENCIL_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);