summaryrefslogtreecommitdiffstats
path: root/src/opengl/gl2paintengineex
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/gl2paintengineex')
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp94
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h3
2 files changed, 80 insertions, 17 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index db306a5..10259d2 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1364,10 +1364,30 @@ void QGL2PaintEngineExPrivate::updateDepthScissorTest()
else
glDisable(GL_DEPTH_TEST);
- if (q->state()->scissorTestEnabled)
+ if (q->state()->scissorTestEnabled) {
+ QRect bounds = q->state()->rectangleClip;
+ if (bounds.isNull() || !q->painter()->hasClipping()) {
+ if (use_system_clip)
+ bounds = systemClip.boundingRect();
+ else
+ bounds = QRect(0, 0, width, height);
+ }
+
glEnable(GL_SCISSOR_TEST);
- else
+ setScissor(bounds);
+ } else {
glDisable(GL_SCISSOR_TEST);
+ }
+}
+
+void QGL2PaintEngineExPrivate::setScissor(const QRect &rect)
+{
+ const int left = rect.left();
+ const int width = rect.width();
+ const int bottom = height - (rect.top() + rect.height());
+ const int height = rect.height();
+
+ glScissor(left, bottom, width, height);
}
void QGL2PaintEngineEx::clipEnabledChanged()
@@ -1383,9 +1403,10 @@ void QGL2PaintEngineEx::clipEnabledChanged()
if (d->use_system_clip) {
state()->currentDepth = -0.5f;
} else {
- glDisable(GL_DEPTH_TEST);
state()->depthTestEnabled = false;
}
+
+ d->updateDepthScissorTest();
}
}
@@ -1457,9 +1478,42 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
if ((d->use_system_clip && rect.contains(d->systemClip.boundingRect()))
|| rect.contains(QRect(0, 0, d->width, d->height)))
return;
+
+ if (state()->rectangleClip.isValid()) {
+ state()->rectangleClip = state()->rectangleClip.intersected(rect.toRect());
+
+ state()->hasRectangleClip = true;
+ state()->scissorTestEnabled = true;
+
+ glEnable(GL_SCISSOR_TEST);
+ d->setScissor(state()->rectangleClip);
+
+ return;
+ }
}
}
+ if (!state()->hasRectangleClip)
+ state()->rectangleClip = QRect();
+
+ if (state()->rectangleClip.isValid() && op != Qt::NoClip && op != Qt::ReplaceClip) {
+ QPainterPath path;
+ path.addRect(state()->rectangleClip);
+
+ state()->rectangleClip = QRect();
+ d->updateDepthScissorTest();
+
+ glDepthFunc(GL_ALWAYS);
+
+ state()->maxDepth = 0.5f;
+ d->writeClip(qtVectorPathForPath(path), state()->maxDepth);
+ state()->currentDepth = 0.25f;
+ state()->depthTestEnabled = true;
+
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+ }
+
switch (op) {
case Qt::NoClip:
if (d->use_system_clip) {
@@ -1480,6 +1534,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
break;
case Qt::ReplaceClip:
d->systemStateChanged();
+ state()->rectangleClip = QRect();
state()->maxDepth = 0.5f;
glDepthFunc(GL_ALWAYS);
d->writeClip(path, state()->maxDepth);
@@ -1518,27 +1573,30 @@ void QGL2PaintEngineExPrivate::systemStateChanged()
q->state()->depthTestEnabled = false;
q->state()->scissorTestEnabled = false;
q->state()->needsDepthBufferClear = true;
+ q->state()->hasRectangleClip = false;
glDisable(GL_SCISSOR_TEST);
q->state()->currentDepth = -0.5f;
q->state()->maxDepth = 0.5f;
- if (use_system_clip) {
- QRect bounds = systemClip.boundingRect();
- if (systemClip.numRects() == 1
- && bounds == QRect(0, 0, width, height))
- {
- q->state()->needsDepthBufferClear = true;
- } else {
- glEnable(GL_SCISSOR_TEST);
+ q->state()->rectangleClip = QRect(0, 0, width, height);
- const int left = bounds.left();
- const int width = bounds.width();
- const int bottom = height - (bounds.top() + bounds.height());
- const int height = bounds.height();
+ if (use_system_clip) {
+ if (systemClip.numRects() == 1) {
+ QRect bounds = systemClip.boundingRect();
+ if (bounds == QRect(0, 0, width, height)) {
+ use_system_clip = false;
+ return;
+ }
- glScissor(left, bottom, width, height);
+ q->state()->rectangleClip = bounds;
+ q->state()->scissorTestEnabled = true;
+ updateDepthScissorTest();
+ } else {
+ q->state()->rectangleClip = QRect();
+ q->state()->scissorTestEnabled = true;
+ updateDepthScissorTest();
QTransform transform = q->state()->matrix;
q->state()->matrix = QTransform();
@@ -1560,7 +1618,6 @@ void QGL2PaintEngineExPrivate::systemStateChanged()
glEnable(GL_DEPTH_TEST);
q->state()->depthTestEnabled = true;
- q->state()->scissorTestEnabled = true;
q->state()->matrix = transform;
q->transformChanged();
@@ -1635,6 +1692,8 @@ QOpenGL2PaintEngineState::QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &oth
currentDepth = other.currentDepth;
maxDepth = other.maxDepth;
canRestoreClip = other.canRestoreClip;
+ rectangleClip = other.rectangleClip;
+ hasRectangleClip = other.hasRectangleClip;
}
QOpenGL2PaintEngineState::QOpenGL2PaintEngineState()
@@ -1645,6 +1704,7 @@ QOpenGL2PaintEngineState::QOpenGL2PaintEngineState()
currentDepth = -0.5f;
maxDepth = 0.5f;
canRestoreClip = true;
+ hasRectangleClip = false;
}
QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState()
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 6a96877..a5fe8a1 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -86,6 +86,8 @@ public:
qreal maxDepth;
bool canRestoreClip;
+ QRect rectangleClip;
+ bool hasRectangleClip;
};
class Q_OPENGL_EXPORT QGL2PaintEngineEx : public QPaintEngineEx
@@ -222,6 +224,7 @@ public:
void writeClip(const QVectorPath &path, float depth);
void updateDepthScissorTest();
+ void setScissor(const QRect &rect);
void regenerateDepthClip();
void systemStateChanged();
uint use_system_clip : 1;