From 89cbb165600de9a557a8a621dc41b93c2a7a2b52 Mon Sep 17 00:00:00 2001
From: Kim Motoyoshi Kalland <kim.kalland@nokia.com>
Date: Mon, 20 Sep 2010 16:31:31 +0200
Subject: Fixed painter path drawing on FBO without stencil buffer.

Task-number: QTBUG-13450
Reviewed-by: Samuel
---
 .../gl2paintengineex/qpaintengineex_opengl2.cpp    | 26 ++++++++++++++++++++++
 src/opengl/qglframebufferobject.cpp                |  4 ++++
 2 files changed, 30 insertions(+)

diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index aa217f6..2347e66 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -866,6 +866,32 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
             if (do_vectorpath_cache)
                 path.makeCacheable();
 
+            if (!device->format().stencil()) {
+                // If there is no stencil buffer, triangulate the path instead.
+
+                QRectF bbox = path.controlPointRect();
+                // If the path doesn't fit within these limits, it is possible that the triangulation will fail.
+                bool withinLimits = (bbox.left() > -0x8000 * inverseScale)
+                                  && (bbox.right() < 0x8000 * inverseScale)
+                                  && (bbox.top() > -0x8000 * inverseScale)
+                                  && (bbox.bottom() < 0x8000 * inverseScale);
+                if (withinLimits) {
+                    QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale));
+
+                    QVarLengthArray<float> vertices(polys.vertices.size());
+                    for (int i = 0; i < polys.vertices.size(); ++i)
+                        vertices[i] = float(inverseScale * polys.vertices.at(i));
+
+                    prepareForDraw(currentBrush.isOpaque());
+                    setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData());
+                    glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.constData());
+                } else {
+                    // We can't handle big, concave painter paths with OpenGL without stencil buffer.
+                    qWarning("Painter path exceeds +/-32767 pixels.");
+                }
+                return;
+            }
+
             // The path is too complicated & needs the stencil technique
             vertexCoordinateArray.clear();
             vertexCoordinateArray.addPath(path, inverseScale, false);
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 9b8a3d1..adbba85 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -324,6 +324,10 @@ void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f,
         fboFormat.setStencil(true);
     } else if (attachment == QGLFramebufferObject::Depth) {
         fboFormat.setDepth(true);
+        fboFormat.setStencil(false);
+    } else {
+        fboFormat.setDepth(false);
+        fboFormat.setStencil(false);
     }
 
     GLenum format = f->format().internalTextureFormat();
-- 
cgit v0.12