diff options
author | DH Kang <kdh.kang@lge.com> | 2014-11-17 16:03:01 +0900 |
---|---|---|
committer | Dominik Holland <dominik.holland@qt.io> | 2020-07-08 10:51:21 +0200 |
commit | 576d3fc2c84f324c035aa924c386f0615002fa16 (patch) | |
tree | a7bac1e2f9078d4fe6523766da5547c56b2706c8 | |
parent | 600b3d4d21f68b93194c040d4fc27f0cca83b768 (diff) |
Set the stencil buffer zone
This only clears the area that update stencil buffer for a better
performance. The information that is to be updated utilizes
information located in the following node's siccor area.
Change-Id: I9a399667ec7ee0a1028e233c899ee49c98e4e622
Task-number: QTBUG-83108
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index a74e82b1bd..131790b19a 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -2427,20 +2427,18 @@ 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)); - 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(); + 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) { qreal invW = 1 / m(3, 3); qreal fx1, fy1, fx2, fy2; - if (noRotate) { + if (noRotate(m)) { 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); + Q_ASSERT(isRotate90(m)); 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; @@ -2459,12 +2457,18 @@ 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 = QRect(ix1, iy1, ix2 - ix1, iy2 - iy1); + m_currentScissorRect = rect; glEnable(GL_SCISSOR_TEST); clipType |= ClipState::ScissorClip; } else { - m_currentScissorRect &= QRect(ix1, iy1, ix2 - ix1, iy2 - iy1); + m_currentScissorRect &= rect; } glScissor(m_currentScissorRect.x(), m_currentScissorRect.y(), m_currentScissorRect.width(), m_currentScissorRect.height()); @@ -2479,9 +2483,29 @@ ClipState::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) m_clipProgram.link(); m_clipMatrixId = m_clipProgram.uniformLocation("matrix"); } + const QSGClipNode *clipNext = clip->clipList(); + 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); |