diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2009-09-01 07:55:13 (GMT) |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2009-09-01 08:56:23 (GMT) |
commit | efe61b3b44c0c391d4c11bd061e531f03bf8fb4a (patch) | |
tree | cf03410fd0031a617b23f645a27d953520b1cbf1 /src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | |
parent | a985aaccfcaf2e24b7094875f2e6f51d80c45997 (diff) | |
download | Qt-efe61b3b44c0c391d4c11bd061e531f03bf8fb4a.zip Qt-efe61b3b44c0c391d4c11bd061e531f03bf8fb4a.tar.gz Qt-efe61b3b44c0c391d4c11bd061e531f03bf8fb4a.tar.bz2 |
Fixed poor utilization of depth buffer range in GL 2 paint engine.
Before this patch we were only able to do 20 or so IntersectClips before
failing, this patch instead adapts to the fixed point nature of typical
depth buffer implementations and lets us do ~2^15 IntersectClip
operations before failing, which should be a reasonable limit for any
real-world application.
Using the following mapping of old floating point depths to integer
depths:
-1.0 -> 0, -0.5 -> 1,
0.0 -> 2, 0.25 -> 3,
0.5 -> 4, 0.625 -> 5,
etc..
Reviewed-by: Tom
Diffstat (limited to 'src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 51 |
1 files changed, 25 insertions, 26 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index a976a02..0c01263 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -380,7 +380,7 @@ void QGL2PaintEngineExPrivate::useSimpleShader() } if (simpleShaderDepthUniformDirty) { - shaderManager->simpleProgram()->setUniformValue("depth", (GLfloat)q->state()->currentDepth); + shaderManager->simpleProgram()->setUniformValue("depth", normalizedDeviceDepth(q->state()->currentDepth)); simpleShaderDepthUniformDirty = false; } } @@ -731,7 +731,6 @@ void QGL2PaintEngineExPrivate::resetGLState() glActiveTexture(GL_TEXTURE0); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); - glDepthFunc(GL_LESS); glDepthMask(true); glClearDepth(1); } @@ -959,7 +958,7 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) } if (depthUniformDirty) { - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Depth), (GLfloat)q->state()->currentDepth); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Depth), normalizedDeviceDepth(q->state()->currentDepth)); depthUniformDirty = false; } @@ -1351,7 +1350,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) if (!d->inRenderText) { glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); - glDepthFunc(GL_LEQUAL); + glDepthFunc(GL_LESS); glDepthMask(false); } @@ -1441,7 +1440,7 @@ void QGL2PaintEngineEx::ensureActive() if (d->needsSync) { glViewport(0, 0, d->width, d->height); glDepthMask(false); - glDepthFunc(GL_LEQUAL); + glDepthFunc(GL_LESS); setState(state()); d->needsSync = false; } @@ -1492,7 +1491,7 @@ void QGL2PaintEngineEx::clipEnabledChanged() d->regenerateDepthClip(); } else { if (d->use_system_clip) { - state()->currentDepth = -0.5f; + state()->currentDepth = 0; } else { state()->depthTestEnabled = false; } @@ -1501,7 +1500,7 @@ void QGL2PaintEngineEx::clipEnabledChanged() } } -void QGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, float depth) +void QGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint depth) { transferMode(BrushDrawingMode); @@ -1510,7 +1509,7 @@ void QGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, float depth) if (q->state()->needsDepthBufferClear) { glDepthMask(true); - glClearDepth(0.5); + glClearDepth(rawDepth(2)); glClear(GL_DEPTH_BUFFER_BIT); q->state()->needsDepthBufferClear = false; glDepthMask(false); @@ -1532,7 +1531,7 @@ void QGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, float depth) glColorMask(false, false, false, false); glDepthMask(true); - shaderManager->simpleProgram()->setUniformValue("depth", depth); + shaderManager->simpleProgram()->setUniformValue("depth", normalizedDeviceDepth(depth)); simpleShaderDepthUniformDirty = true; glEnable(GL_DEPTH_TEST); @@ -1596,12 +1595,12 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) glDepthFunc(GL_ALWAYS); - state()->maxDepth = 0.5f; + state()->maxDepth = 4; d->writeClip(qtVectorPathForPath(path), state()->maxDepth); - state()->currentDepth = 0.25f; + state()->currentDepth = 3; state()->depthTestEnabled = true; - glDepthFunc(GL_LEQUAL); + glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); } @@ -1610,7 +1609,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) if (d->use_system_clip) { glEnable(GL_DEPTH_TEST); state()->depthTestEnabled = true; - state()->currentDepth = -0.5; + state()->currentDepth = 0; } else { glDisable(GL_DEPTH_TEST); state()->depthTestEnabled = false; @@ -1618,18 +1617,18 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) state()->canRestoreClip = false; break; case Qt::IntersectClip: - state()->maxDepth = (1.0f + state()->maxDepth) * 0.5; + ++state()->maxDepth; d->writeClip(path, state()->maxDepth); - state()->currentDepth = 1.5 * state()->maxDepth - 0.5f; + state()->currentDepth = state()->maxDepth - 1; state()->depthTestEnabled = true; break; case Qt::ReplaceClip: d->systemStateChanged(); state()->rectangleClip = QRect(); - state()->maxDepth = 0.5f; + state()->maxDepth = 4; glDepthFunc(GL_ALWAYS); d->writeClip(path, state()->maxDepth); - state()->currentDepth = 0.25f; + state()->currentDepth = 3; state()->canRestoreClip = false; state()->depthTestEnabled = true; break; @@ -1641,7 +1640,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) break; } - glDepthFunc(GL_LEQUAL); + glDepthFunc(GL_LESS); if (state()->depthTestEnabled) { glEnable(GL_DEPTH_TEST); d->simpleShaderDepthUniformDirty = true; @@ -1672,8 +1671,8 @@ void QGL2PaintEngineExPrivate::systemStateChanged() glDisable(GL_SCISSOR_TEST); - q->state()->currentDepth = -0.5f; - q->state()->maxDepth = 0.5f; + q->state()->currentDepth = 1; + q->state()->maxDepth = 4; q->state()->rectangleClip = QRect(0, 0, width, height); @@ -1708,8 +1707,8 @@ void QGL2PaintEngineExPrivate::systemStateChanged() path.addRegion(systemClip); glDepthFunc(GL_ALWAYS); - writeClip(qtVectorPathForPath(path), 0.0f); - glDepthFunc(GL_LEQUAL); + writeClip(qtVectorPathForPath(path), 2); + glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); q->state()->depthTestEnabled = true; @@ -1718,7 +1717,7 @@ void QGL2PaintEngineExPrivate::systemStateChanged() q->transformChanged(); } - q->state()->currentDepth = -0.5f; + q->state()->currentDepth = 1; simpleShaderDepthUniformDirty = true; depthUniformDirty = true; } @@ -1757,7 +1756,7 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) if (old_state && old_state != s && old_state->canRestoreClip) { d->updateDepthScissorTest(); glDepthMask(false); - glDepthFunc(GL_LEQUAL); + glDepthFunc(GL_LESS); s->maxDepth = old_state->maxDepth; } else { d->regenerateDepthClip(); @@ -1802,8 +1801,8 @@ QOpenGL2PaintEngineState::QOpenGL2PaintEngineState() needsDepthBufferClear = true; depthTestEnabled = false; scissorTestEnabled = false; - currentDepth = -0.5f; - maxDepth = 0.5f; + currentDepth = 1; + maxDepth = 4; canRestoreClip = true; hasRectangleClip = false; } |