summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp35
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp21
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h4
-rw-r--r--src/opengl/gl2paintengineex/qtriangulatingstroker.cpp1
-rw-r--r--src/opengl/qgl.cpp5
-rw-r--r--src/opengl/qgl_x11.cpp1
-rw-r--r--src/opengl/qglframebufferobject.cpp4
-rw-r--r--src/opengl/qglpixelbuffer.cpp8
-rw-r--r--src/opengl/qglpixelbuffer_win.cpp34
-rw-r--r--src/opengl/qpaintengine_opengl.cpp9
-rw-r--r--src/opengl/qpixmapdata_gl_p.h1
-rw-r--r--src/opengl/qwindowsurface_gl.cpp17
12 files changed, 110 insertions, 30 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index b762bcc0f6..d89ef08d90 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);
@@ -1525,8 +1551,15 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
vertexCoordinates->clear();
textureCoordinates->clear();
+ bool supportsSubPixelPositions = staticTextItem->fontEngine->supportsSubPixelPositions();
for (int i=0; i<staticTextItem->numGlyphs; ++i) {
- const QTextureGlyphCache::Coord &c = cache->coords.value(staticTextItem->glyphs[i]);
+ QFixed subPixelPosition;
+ if (supportsSubPixelPositions)
+ subPixelPosition = cache->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
+
+ QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);
+
+ const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
int x = staticTextItem->glyphPositions[i].x.toInt() + c.baseLineX - margin;
int y = staticTextItem->glyphPositions[i].y.toInt() - c.baseLineY - margin;
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index 53a2f3ac1a..f8e34d4286 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -216,7 +216,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
pex->updateClipScissorTest();
}
-void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
+void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
{
if (ctx == 0) {
qWarning("QGLTextureGlyphCache::fillTexture: Called with no context");
@@ -225,7 +225,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
if (pex == 0 || ctx->d_ptr->workaround_brokenFBOReadBack) {
- QImageTextureGlyphCache::fillTexture(c, glyph);
+ QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition);
glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
const QImage &texture = image();
@@ -238,7 +238,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
return;
}
- QImage mask = textureMapForGlyph(glyph);
+ QImage mask = textureMapForGlyph(glyph, subPixelPosition);
const int maskWidth = mask.width();
const int maskHeight = mask.height();
@@ -291,4 +291,19 @@ int QGLTextureGlyphCache::glyphPadding() const
return 1;
}
+int QGLTextureGlyphCache::maxTextureWidth() const
+{
+ if (ctx == 0)
+ return QImageTextureGlyphCache::maxTextureWidth();
+ else
+ return ctx->d_ptr->maxTextureSize();
+}
+
+int QGLTextureGlyphCache::maxTextureHeight() const
+{
+ if (ctx == 0)
+ return QImageTextureGlyphCache::maxTextureHeight();
+ else
+ return ctx->d_ptr->maxTextureSize();
+}
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index 2ae3a6420f..ada47e9e5d 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -106,8 +106,10 @@ public:
virtual void createTextureData(int width, int height);
virtual void resizeTextureData(int width, int height);
- virtual void fillTexture(const Coord &c, glyph_t glyph);
+ virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition);
virtual int glyphPadding() const;
+ virtual int maxTextureWidth() const;
+ virtual int maxTextureHeight() const;
inline GLuint texture() const {
QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
index 9bc099df38..7b0b8a2180 100644
--- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
+++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
@@ -509,6 +509,7 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c
m_dash_stroker.setDashPattern(pen.dashPattern());
m_dash_stroker.setStrokeWidth(cosmetic ? width * m_inv_scale : width);
+ m_dash_stroker.setDashOffset(pen.dashOffset());
m_dash_stroker.setMiterLimit(pen.miterLimit());
m_dash_stroker.setClipRect(clip);
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 63d4a6c2bc..ec191e1cce 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -110,11 +110,10 @@ extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
#endif
struct QGLThreadContext {
-#ifdef QT_OPENGL_ES
~QGLThreadContext() {
- eglReleaseThread();
+ if (context)
+ context->doneCurrent();
}
-#endif
QGLContext *context;
};
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
index bfb232da89..f3a4c95326 100644
--- a/src/opengl/qgl_x11.cpp
+++ b/src/opengl/qgl_x11.cpp
@@ -54,6 +54,7 @@
#include <private/qt_x11_p.h>
#include <private/qpixmap_x11_p.h>
#include <private/qimagepixmapcleanuphooks_p.h>
+#include <private/qunicodetables_p.h>
#ifdef Q_OS_HPUX
// for GLXPBuffer
#include <private/qglpixelbuffer_p.h>
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 660201ba4c..cee950aa5e 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();
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index da2974ca0d..2ec345da57 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -67,7 +67,13 @@
when the pbuffer contents change, eliminating the need for
additional copy operations. This is supported only on Windows
and Mac OS X systems that provide the \c render_texture
- extension.
+ extension. Note that under Windows, a multi-sampled pbuffer
+ can't be used in conjunction with the \c render_texture
+ extension. If a multi-sampled pbuffer is requested under
+ Windows, the \c render_texture extension is turned off for that
+ pbuffer.
+
+
\endlist
diff --git a/src/opengl/qglpixelbuffer_win.cpp b/src/opengl/qglpixelbuffer_win.cpp
index df83566d19..1da0aad294 100644
--- a/src/opengl/qglpixelbuffer_win.cpp
+++ b/src/opengl/qglpixelbuffer_win.cpp
@@ -167,6 +167,11 @@ typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, con
#define WGL_FLOAT_COMPONENTS_NV 0x20B0
#endif
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
QGLFormat pfiToQGLFormat(HDC hdc, int pfi);
static void qt_format_to_attrib_list(bool has_render_texture, const QGLFormat &f, int attribs[])
@@ -226,14 +231,12 @@ static void qt_format_to_attrib_list(bool has_render_texture, const QGLFormat &f
attribs[i++] = WGL_FLOAT_COMPONENTS_NV;
attribs[i++] = TRUE;
}
- // sample buffers doesn't work in conjunction with the render_texture extension
- // so igonre that for now
- // if (f.sampleBuffers()) {
- // attribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
- // attribs[i++] = 1;
- // attribs[i++] = WGL_SAMPLES_ARB;
- // attribs[i++] = f.samples() == -1 ? 16 : f.samples();
- // }
+ if (f.sampleBuffers()) {
+ attribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
+ attribs[i++] = 1;
+ attribs[i++] = WGL_SAMPLES_ARB;
+ attribs[i++] = f.samples() == -1 ? 16 : f.samples();
+ }
attribs[i] = 0;
}
@@ -256,12 +259,17 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge
dc = wglGetCurrentDC();
Q_ASSERT(dc);
- PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
- (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
+ // sample buffers doesn't work in conjunction with the render_texture extension
+ if (f.sampleBuffers()) {
+ has_render_texture = false;
+ } else {
+ PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
+ (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
- if (wglGetExtensionsStringARB) {
- QString extensions(QLatin1String(wglGetExtensionsStringARB(dc)));
- has_render_texture = extensions.contains(QLatin1String("WGL_ARB_render_texture"));
+ if (wglGetExtensionsStringARB) {
+ QString extensions(QLatin1String(wglGetExtensionsStringARB(dc)));
+ has_render_texture = extensions.contains(QLatin1String("WGL_ARB_render_texture"));
+ }
}
int attribs[40];
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 12c487d449..58778ea86c 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -921,6 +921,7 @@ static inline QPainterPath strokeForPath(const QPainterPath &path, const QPen &c
stroker.setCapStyle(cpen.capStyle());
stroker.setJoinStyle(cpen.joinStyle());
stroker.setMiterLimit(cpen.miterLimit());
+ stroker.setDashOffset(cpen.dashOffset());
qreal width = cpen.widthF();
if (width == 0)
@@ -4734,9 +4735,11 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine,
font_cache = new QGLFontGlyphHash;
// qDebug() << "new context" << context << font_cache;
qt_context_cache.insert(context, font_cache);
- if (context->isValid() && context->device()->devType() == QInternal::Widget) {
- QWidget *widget = static_cast<QWidget *>(context->device());
- connect(widget, SIGNAL(destroyed(QObject*)), SLOT(widgetDestroyed(QObject*)));
+ if (context->isValid()) {
+ if (context->device()->devType() == QInternal::Widget) {
+ QWidget *widget = static_cast<QWidget *>(context->device());
+ connect(widget, SIGNAL(destroyed(QObject*)), SLOT(widgetDestroyed(QObject*)));
+ }
connect(QGLSignalProxy::instance(),
SIGNAL(aboutToDestroyContext(const QGLContext*)),
SLOT(cleanupContext(const QGLContext*)));
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
index 4cb67b0952..f000993dfc 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -168,6 +168,7 @@ private:
mutable QGLPixmapGLPaintDevice m_glDevice;
friend class QGLPixmapGLPaintDevice;
+ friend class QMeeGoPixmapData;
};
QT_END_NAMESPACE
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 52abe5a60b..bc4912bd07 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -190,7 +190,10 @@ public:
QGLWidget *shareWidget() {
if (!initializing && !widget && !cleanedUp) {
initializing = true;
- widget = new QGLWidget;
+
+ widget = new QGLWidget(QGLFormat(QGL::SingleBuffer | QGL::NoDepthBuffer | QGL::NoStencilBuffer));
+ widget->resize(1, 1);
+
// We dont need this internal widget to appear in QApplication::topLevelWidgets()
if (QWidgetPrivate::allWidgets)
QWidgetPrivate::allWidgets->remove(widget);
@@ -342,12 +345,14 @@ QGLWindowSurface::~QGLWindowSurface()
void QGLWindowSurface::deleted(QObject *object)
{
- // Make sure that the fbo is destroyed before destroying its context.
- delete d_ptr->fbo;
- d_ptr->fbo = 0;
-
QWidget *widget = qobject_cast<QWidget *>(object);
if (widget) {
+ if (widget == window()) {
+ // Make sure that the fbo is destroyed before destroying its context.
+ delete d_ptr->fbo;
+ d_ptr->fbo = 0;
+ }
+
QWidgetPrivate *widgetPrivate = widget->d_func();
if (widgetPrivate->extraData()) {
union { QGLContext **ctxPtr; void **voidPtr; };
@@ -421,6 +426,8 @@ QPaintDevice *QGLWindowSurface::paintDevice()
QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
ctx->makeCurrent();
+
+ Q_ASSERT(d_ptr->fbo);
return d_ptr->fbo;
}