diff options
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 35 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 21 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h | 4 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtriangulatingstroker.cpp | 1 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 5 | ||||
-rw-r--r-- | src/opengl/qgl_x11.cpp | 1 | ||||
-rw-r--r-- | src/opengl/qglframebufferobject.cpp | 4 | ||||
-rw-r--r-- | src/opengl/qglpixelbuffer.cpp | 8 | ||||
-rw-r--r-- | src/opengl/qglpixelbuffer_win.cpp | 34 | ||||
-rw-r--r-- | src/opengl/qpaintengine_opengl.cpp | 9 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl_p.h | 1 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_gl.cpp | 17 |
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; } |