diff options
author | Gunnar Sletta <gunnar@trolltech.com> | 2009-12-01 08:17:32 (GMT) |
---|---|---|
committer | Gunnar Sletta <gunnar@trolltech.com> | 2009-12-01 08:17:32 (GMT) |
commit | b5b9faa7cdc877f8ab32a8d5ae480b5857761409 (patch) | |
tree | 0d09f4e554aa01da3714cdc96af707a49b44ed93 /src/opengl | |
parent | 4f4f1e612488f400b2b139eaf7fea940fb6d7e7c (diff) | |
parent | bc992c8e40fcfdcfe0015dd88dda77c318c10a55 (diff) | |
download | Qt-b5b9faa7cdc877f8ab32a8d5ae480b5857761409.zip Qt-b5b9faa7cdc877f8ab32a8d5ae480b5857761409.tar.gz Qt-b5b9faa7cdc877f8ab32a8d5ae480b5857761409.tar.bz2 |
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.6
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 12 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtriangulatingstroker.cpp | 205 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtriangulatingstroker_p.h | 158 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 58 | ||||
-rw-r--r-- | src/opengl/qgl_mac.mm | 1 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 3 | ||||
-rw-r--r-- | src/opengl/qgl_x11.cpp | 27 | ||||
-rw-r--r-- | src/opengl/qpaintengine_opengl.cpp | 20 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_gl.cpp | 2 |
9 files changed, 277 insertions, 209 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index e281729..6a708b4 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -158,8 +158,8 @@ QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyph , m_height(0) { glGenFramebuffers(1, &m_fbo); - connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext *)), - SLOT(contextDestroyed(const QGLContext *))); + connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)), + SLOT(contextDestroyed(const QGLContext*))); } QGLTextureGlyphCache::~QGLTextureGlyphCache() @@ -1454,7 +1454,8 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem drawCached = false; // don't try to cache huge fonts - if (ti.fontEngine->fontDef.pixelSize * qSqrt(s->matrix.determinant()) >= 64) + const qreal pixelSize = ti.fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64) drawCached = false; QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 @@ -1775,13 +1776,10 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->glyphCacheType = QFontEngineGlyphCache::Raster_A8; #if !defined(QT_OPENGL_ES_2) - if (!d->device->format().alpha() #if defined(Q_WS_WIN) - && qt_cleartype_enabled + if (qt_cleartype_enabled) #endif - ) { d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask; - } #endif #if defined(QT_OPENGL_ES_2) diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index 1478b09..6082f49 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -209,6 +209,65 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen) } } +void QTriangulatingStroker::moveTo(const qreal *pts) +{ + m_cx = pts[0]; + m_cy = pts[1]; + + float x2 = pts[2]; + float y2 = pts[3]; + normalVector(m_cx, m_cy, x2, y2, &m_nvx, &m_nvy); + + + // To acheive jumps we insert zero-area tringles. This is done by + // adding two identical points in both the end of previous strip + // and beginning of next strip + bool invisibleJump = m_vertices.size(); + + switch (m_cap_style) { + case Qt::FlatCap: + if (invisibleJump) { + m_vertices.add(m_cx + m_nvx); + m_vertices.add(m_cy + m_nvy); + } + break; + case Qt::SquareCap: { + float sx = m_cx - m_nvy; + float sy = m_cy + m_nvx; + if (invisibleJump) { + m_vertices.add(sx + m_nvx); + m_vertices.add(sy + m_nvy); + } + emitLineSegment(sx, sy, m_nvx, m_nvy); + break; } + case Qt::RoundCap: { + QVarLengthArray<float> points; + arcPoints(m_cx, m_cy, m_cx + m_nvx, m_cy + m_nvy, m_cx - m_nvx, m_cy - m_nvy, points); + m_vertices.resize(m_vertices.size() + points.size() + 2 * int(invisibleJump)); + int count = m_vertices.size(); + int front = 0; + int end = points.size() / 2; + while (front != end) { + m_vertices.at(--count) = points[2 * end - 1]; + m_vertices.at(--count) = points[2 * end - 2]; + --end; + if (front == end) + break; + m_vertices.at(--count) = points[2 * front + 1]; + m_vertices.at(--count) = points[2 * front + 0]; + ++front; + } + + if (invisibleJump) { + m_vertices.at(count - 1) = m_vertices.at(count + 1); + m_vertices.at(count - 2) = m_vertices.at(count + 0); + } + break; } + default: break; // ssssh gcc... + } + emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); +} + void QTriangulatingStroker::cubicTo(const qreal *pts) { const QPointF *p = (const QPointF *) pts; @@ -246,6 +305,152 @@ void QTriangulatingStroker::cubicTo(const qreal *pts) m_nvy = vy; } +void QTriangulatingStroker::join(const qreal *pts) +{ + // Creates a join to the next segment (m_cx, m_cy) -> (pts[0], pts[1]) + normalVector(m_cx, m_cy, pts[0], pts[1], &m_nvx, &m_nvy); + + switch (m_join_style) { + case Qt::BevelJoin: + break; + case Qt::SvgMiterJoin: + case Qt::MiterJoin: { + // Find out on which side the join should be. + int count = m_vertices.size(); + float prevNvx = m_vertices.at(count - 2) - m_cx; + float prevNvy = m_vertices.at(count - 1) - m_cy; + float xprod = prevNvx * m_nvy - prevNvy * m_nvx; + float px, py, qx, qy; + + // If the segments are parallel, use bevel join. + if (qFuzzyIsNull(xprod)) + break; + + // Find the corners of the previous and next segment to join. + if (xprod < 0) { + px = m_vertices.at(count - 2); + py = m_vertices.at(count - 1); + qx = m_cx - m_nvx; + qy = m_cy - m_nvy; + } else { + px = m_vertices.at(count - 4); + py = m_vertices.at(count - 3); + qx = m_cx + m_nvx; + qy = m_cy + m_nvy; + } + + // Find intersection point. + float pu = px * prevNvx + py * prevNvy; + float qv = qx * m_nvx + qy * m_nvy; + float ix = (m_nvy * pu - prevNvy * qv) / xprod; + float iy = (prevNvx * qv - m_nvx * pu) / xprod; + + // Check that the distance to the intersection point is less than the miter limit. + if ((ix - px) * (ix - px) + (iy - py) * (iy - py) <= m_miter_limit * m_miter_limit) { + m_vertices.add(ix); + m_vertices.add(iy); + m_vertices.add(ix); + m_vertices.add(iy); + } + // else + // Do a plain bevel join if the miter limit is exceeded or if + // the lines are parallel. This is not what the raster + // engine's stroker does, but it is both faster and similar to + // what some other graphics API's do. + + break; } + case Qt::RoundJoin: { + QVarLengthArray<float> points; + int count = m_vertices.size(); + float prevNvx = m_vertices.at(count - 2) - m_cx; + float prevNvy = m_vertices.at(count - 1) - m_cy; + if (m_nvx * prevNvy - m_nvy * prevNvx < 0) { + arcPoints(0, 0, m_nvx, m_nvy, -prevNvx, -prevNvy, points); + for (int i = points.size() / 2; i > 0; --i) + emitLineSegment(m_cx, m_cy, points[2 * i - 2], points[2 * i - 1]); + } else { + arcPoints(0, 0, -prevNvx, -prevNvy, m_nvx, m_nvy, points); + for (int i = 0; i < points.size() / 2; ++i) + emitLineSegment(m_cx, m_cy, points[2 * i + 0], points[2 * i + 1]); + } + break; } + default: break; // gcc warn-- + } + + emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); +} + +void QTriangulatingStroker::endCap(const qreal *) +{ + switch (m_cap_style) { + case Qt::FlatCap: + break; + case Qt::SquareCap: + emitLineSegment(m_cx + m_nvy, m_cy - m_nvx, m_nvx, m_nvy); + break; + case Qt::RoundCap: { + QVarLengthArray<float> points; + int count = m_vertices.size(); + arcPoints(m_cx, m_cy, m_vertices.at(count - 2), m_vertices.at(count - 1), m_vertices.at(count - 4), m_vertices.at(count - 3), points); + int front = 0; + int end = points.size() / 2; + while (front != end) { + m_vertices.add(points[2 * end - 2]); + m_vertices.add(points[2 * end - 1]); + --end; + if (front == end) + break; + m_vertices.add(points[2 * front + 0]); + m_vertices.add(points[2 * front + 1]); + ++front; + } + break; } + default: break; // to shut gcc up... + } +} + +void QTriangulatingStroker::arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points) +{ + float dx1 = fromX - cx; + float dy1 = fromY - cy; + float dx2 = toX - cx; + float dy2 = toY - cy; + + // while more than 180 degrees left: + while (dx1 * dy2 - dx2 * dy1 < 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // while more than 90 degrees left: + while (dx1 * dx2 + dy1 * dy2 < 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // while more than 0 degrees left: + while (dx1 * dy2 - dx2 * dy1 > 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // remove last point which was rotated beyond [toX, toY]. + if (!points.isEmpty()) + points.resize(points.size() - 2); +} + static void qdashprocessor_moveTo(qreal x, qreal y, void *data) { ((QDashedStrokeProcessor *) data)->addElement(QPainterPath::MoveToElement, x, y); diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h index a0117d5..2dba0ce 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h @@ -43,6 +43,7 @@ #define QTRIANGULATINGSTROKER_P_H #include <private/qdatabuffer_p.h> +#include <qvarlengtharray.h> #include <private/qvectorpath_p.h> #include <private/qbezier_p.h> #include <private/qnumeric_p.h> @@ -62,13 +63,13 @@ public: private: inline void emitLineSegment(float x, float y, float nx, float ny); - inline void moveTo(const qreal *pts); + void moveTo(const qreal *pts); inline void lineTo(const qreal *pts); void cubicTo(const qreal *pts); - inline void join(const qreal *pts); + void join(const qreal *pts); inline void normalVector(float x1, float y1, float x2, float y2, float *nx, float *ny); - inline void endCap(const qreal *pts); - inline void arc(float x, float y); + void endCap(const qreal *pts); + void arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points); void endCapOrJoinClosed(const qreal *start, const qreal *cur, bool implicitClose, bool endsAtStart); @@ -116,10 +117,6 @@ private: qreal m_inv_scale; }; - - - - inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, float y2, float *nx, float *ny) { @@ -139,8 +136,6 @@ inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, fl *ny = dx * pw; } - - inline void QTriangulatingStroker::emitLineSegment(float x, float y, float vx, float vy) { m_vertices.add(x + vx); @@ -149,103 +144,6 @@ inline void QTriangulatingStroker::emitLineSegment(float x, float y, float vx, f m_vertices.add(y - vy); } - - -// We draw a full circle for any round join or round cap which is a -// bit of overkill... -inline void QTriangulatingStroker::arc(float x, float y) -{ - float dx = m_width; - float dy = 0; - for (int i=0; i<=m_roundness; ++i) { - float tmpx = dx * m_cos_theta - dy * m_sin_theta; - float tmpy = dx * m_sin_theta + dy * m_cos_theta; - dx = tmpx; - dy = tmpy; - emitLineSegment(x, y, dx, dy); - } -} - - - -inline void QTriangulatingStroker::endCap(const qreal *pts) -{ - switch (m_cap_style) { - case Qt::FlatCap: - break; - case Qt::SquareCap: { - float dx = m_cx - *(pts - 2); - float dy = m_cy - *(pts - 1); - - float len = m_width / sqrt(dx * dx + dy * dy); - dx = dx * len; - dy = dy * len; - - emitLineSegment(m_cx + dx, m_cy + dy, m_nvx, m_nvy); - break; } - case Qt::RoundCap: - arc(m_cx, m_cy); - break; - default: break; // to shut gcc up... - } -} - - -void QTriangulatingStroker::moveTo(const qreal *pts) -{ - m_cx = pts[0]; - m_cy = pts[1]; - - float x2 = pts[2]; - float y2 = pts[3]; - normalVector(m_cx, m_cy, x2, y2, &m_nvx, &m_nvy); - - - // To acheive jumps we insert zero-area tringles. This is done by - // adding two identical points in both the end of previous strip - // and beginning of next strip - bool invisibleJump = m_vertices.size(); - - switch (m_cap_style) { - case Qt::FlatCap: - if (invisibleJump) { - m_vertices.add(m_cx + m_nvx); - m_vertices.add(m_cy + m_nvy); - } - break; - case Qt::SquareCap: { - float dx = x2 - m_cx; - float dy = y2 - m_cy; - float len = m_width / sqrt(dx * dx + dy * dy); - dx = dx * len; - dy = dy * len; - float sx = m_cx - dx; - float sy = m_cy - dy; - if (invisibleJump) { - m_vertices.add(sx + m_nvx); - m_vertices.add(sy + m_nvy); - } - emitLineSegment(sx, sy, m_nvx, m_nvy); - break; } - case Qt::RoundCap: - if (invisibleJump) { - m_vertices.add(m_cx + m_nvx); - m_vertices.add(m_cy + m_nvy); - } - - // This emitLineSegment is not needed for the arc, but we need - // to start where we put the invisibleJump vertex, otherwise - // we'll have visible triangles between subpaths. - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); - arc(m_cx, m_cy); - break; - default: break; // ssssh gcc... - } - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); -} - - - void QTriangulatingStroker::lineTo(const qreal *pts) { emitLineSegment(pts[0], pts[1], m_nvx, m_nvy); @@ -253,52 +151,6 @@ void QTriangulatingStroker::lineTo(const qreal *pts) m_cy = pts[1]; } - - -void QTriangulatingStroker::join(const qreal *pts) -{ - // Creates a join to the next segment (m_cx, m_cy) -> (pts[0], pts[1]) - normalVector(m_cx, m_cy, pts[0], pts[1], &m_nvx, &m_nvy); - - switch (m_join_style) { - case Qt::BevelJoin: - break; - case Qt::MiterJoin: { - int p1 = m_vertices.size() - 6; - int p2 = m_vertices.size() - 2; - QLineF line(m_vertices.at(p1), m_vertices.at(p1+1), - m_vertices.at(p2), m_vertices.at(p2+1)); - QLineF nextLine(m_cx - m_nvx, m_cy - m_nvy, - pts[0] - m_nvx, pts[1] - m_nvy); - - QPointF isect; - if (line.intersect(nextLine, &isect) != QLineF::NoIntersection - && QLineF(line.p2(), isect).length() <= m_miter_limit) { - // The intersection point mirrored over the m_cx, m_cy point - m_vertices.add(m_cx - (isect.x() - m_cx)); - m_vertices.add(m_cy - (isect.y() - m_cy)); - - // The intersection point - m_vertices.add(isect.x()); - m_vertices.add(isect.y()); - } - // else - // Do a plain bevel join if the miter limit is exceeded or if - // the lines are parallel. This is not what the raster - // engine's stroker does, but it is both faster and similar to - // what some other graphics API's do. - - break; } - case Qt::RoundJoin: - arc(m_cx, m_cy); - break; - - default: break; // gcc warn-- - } - - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); -} - QT_END_NAMESPACE #endif diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index f8a2ea4..d5ca218 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -184,8 +184,13 @@ public: engineType = QPaintEngine::OpenGL2; #else // We can't do this in the constructor for this object because it - // needs to be called *before* the QApplication constructor + // needs to be called *before* the QApplication constructor. + // Also check for the FragmentProgram extension in conjunction with + // the 2.0 version flag, to cover the case where we export the display + // from an old GL 1.1 server to a GL 2.x client. In that case we can't + // use GL 2.0. if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) + && (QGLExtensions::glExtensions & QGLExtensions::FragmentProgram) && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty()) engineType = QPaintEngine::OpenGL2; else @@ -2170,8 +2175,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G int tx_h = qt_next_power_of_two(image.height()); QImage img = image; - if (( !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) && - !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0) ) + if (!(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures) + && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0) && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height()))) { img = img.scaled(tx_w, tx_h); @@ -2192,9 +2197,9 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G bool genMipmap = false; #endif if (glFormat.directRendering() - && QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap + && (QGLExtensions::glExtensions & QGLExtensions::GenerateMipmap) && target == GL_TEXTURE_2D - && options & QGLContext::MipmapBindOption) + && (options & QGLContext::MipmapBindOption)) { #ifdef QGL_BIND_TEXTURE_DEBUG printf(" - generating mipmaps (%d ms)\n", time.elapsed()); @@ -2220,7 +2225,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G bool premul = options & QGLContext::PremultipliedAlphaBindOption; GLenum externalFormat; GLuint pixel_type; - if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2) { + if (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) { externalFormat = GL_BGRA; pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV; } else { @@ -4886,54 +4891,59 @@ QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, void QGLExtensions::init_extensions() { - QString extensions = QLatin1String(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))); - if (extensions.contains(QLatin1String("texture_rectangle"))) + QList<QByteArray> extensions = QByteArray(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))).split(' '); + if (extensions.contains("GL_ARB_texture_rectangle")) glExtensions |= TextureRectangle; - if (extensions.contains(QLatin1String("multisample"))) + if (extensions.contains("GL_ARB_multisample")) glExtensions |= SampleBuffers; - if (extensions.contains(QLatin1String("generate_mipmap"))) + if (extensions.contains("GL_SGIS_generate_mipmap")) glExtensions |= GenerateMipmap; - if (extensions.contains(QLatin1String("texture_compression_s3tc"))) + if (extensions.contains("GL_EXT_texture_compression_s3tc")) glExtensions |= TextureCompression; - if (extensions.contains(QLatin1String("ARB_fragment_program"))) + if (extensions.contains("GL_ARB_fragment_program")) glExtensions |= FragmentProgram; - if (extensions.contains(QLatin1String("mirrored_repeat"))) + if (extensions.contains("GL_ARB_texture_mirrored_repeat")) glExtensions |= MirroredRepeat; - if (extensions.contains(QLatin1String("EXT_framebuffer_object"))) + if (extensions.contains("GL_EXT_framebuffer_object")) glExtensions |= FramebufferObject; - if (extensions.contains(QLatin1String("EXT_stencil_two_side"))) + if (extensions.contains("GL_EXT_stencil_two_side")) glExtensions |= StencilTwoSide; - if (extensions.contains(QLatin1String("EXT_stencil_wrap"))) + if (extensions.contains("GL_EXT_stencil_wrap")) glExtensions |= StencilWrap; - if (extensions.contains(QLatin1String("EXT_packed_depth_stencil"))) + if (extensions.contains("GL_EXT_packed_depth_stencil")) glExtensions |= PackedDepthStencil; - if (extensions.contains(QLatin1String("GL_NV_float_buffer"))) + if (extensions.contains("GL_NV_float_buffer")) glExtensions |= NVFloatBuffer; - if (extensions.contains(QLatin1String("ARB_pixel_buffer_object"))) + if (extensions.contains("GL_ARB_pixel_buffer_object")) glExtensions |= PixelBufferObject; #if defined(QT_OPENGL_ES_2) glExtensions |= FramebufferObject; glExtensions |= GenerateMipmap; #endif #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL) - if (extensions.contains(QLatin1String("OES_framebuffer_object"))) + if (extensions.contains("GL_OES_framebuffer_object")) glExtensions |= FramebufferObject; #endif #if defined(QT_OPENGL_ES) - if (extensions.contains(QLatin1String("OES_packed_depth_stencil"))) + if (extensions.contains("GL_OES_packed_depth_stencil")) glExtensions |= PackedDepthStencil; #endif - if (extensions.contains(QLatin1String("ARB_framebuffer_object"))) { + if (extensions.contains("GL_ARB_framebuffer_object")) { // ARB_framebuffer_object also includes EXT_framebuffer_blit. glExtensions |= FramebufferObject; glExtensions |= FramebufferBlit; } - if (extensions.contains(QLatin1String("EXT_framebuffer_blit"))) + + if (extensions.contains("GL_EXT_framebuffer_blit")) glExtensions |= FramebufferBlit; - if (extensions.contains(QLatin1String("GL_ARB_texture_non_power_of_two"))) + if (extensions.contains("GL_ARB_texture_non_power_of_two")) glExtensions |= NPOTTextures; + if (extensions.contains("GL_EXT_bgra")) + glExtensions |= BGRATextureFormat; + + QGLContext cx(QGLFormat::defaultFormat()); if (glExtensions & TextureCompression) { qt_glCompressedTexImage2DARB = (pfn_glCompressedTexImage2DARB) cx.getProcAddress(QLatin1String("glCompressedTexImage2DARB")); diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index 063082b..4dd822d 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -460,6 +460,7 @@ void QGLContext::reset() if (d->cx) aglDestroyContext((AGLContext)d->cx); #else + QMacCocoaAutoReleasePool pool; [static_cast<NSOpenGLContext *>(d->cx) release]; #endif d->cx = 0; diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 45b2942..8e472e5 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -375,7 +375,8 @@ public: NVFloatBuffer = 0x00000400, PixelBufferObject = 0x00000800, FramebufferBlit = 0x00001000, - NPOTTextures = 0x00002000 + NPOTTextures = 0x00002000, + BGRATextureFormat = 0x00004000 }; Q_DECLARE_FLAGS(Extensions, Extension) diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 899047a..a037282 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -343,8 +343,8 @@ void* qglx_getProcAddress(const char* procName) static bool triedResolvingGlxGetProcAddress = false; if (!triedResolvingGlxGetProcAddress) { triedResolvingGlxGetProcAddress = true; - QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); - if (glxExt.contains(QLatin1String("GLX_ARB_get_proc_address"))) { + QList<QByteArray> glxExt = QByteArray(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)).split(' '); + if (glxExt.contains("GLX_ARB_get_proc_address")) { #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) void *handle = dlopen(NULL, RTLD_LAZY); if (handle) { @@ -523,8 +523,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) if (!d->gpm) return false; } - QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); - if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) { + QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(xinfo->display(), xinfo->screen())).split(' '); + if (glxExt.contains("GLX_SGI_video_sync")) { if (d->glFormat.swapInterval() == -1) d->glFormat.setSwapInterval(0); } else { @@ -874,8 +874,9 @@ void QGLContext::swapBuffers() const static qt_glXWaitVideoSyncSGI glXWaitVideoSyncSGI = 0; static bool resolved = false; if (!resolved) { - QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); - if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) { + const QX11Info *xinfo = qt_x11Info(d->paintDevice); + QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(xinfo->display(), xinfo->screen())).split(' '); + if (glxExt.contains("GLX_SGI_video_sync")) { glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI"); glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI"); } @@ -1106,8 +1107,8 @@ void *QGLContext::getProcAddress(const QString &proc) const if (resolved && !glXGetProcAddressARB) return 0; if (!glXGetProcAddressARB) { - QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); - if (glxExt.contains(QLatin1String("GLX_ARB_get_proc_address"))) { + QList<QByteArray> glxExt = QByteArray(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)).split(' '); + if (glxExt.contains("GLX_ARB_get_proc_address")) { #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) void *handle = dlopen(NULL, RTLD_LAZY); if (handle) { @@ -1594,7 +1595,7 @@ typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int); static qt_glXBindTexImageEXT glXBindTexImageEXT = 0; static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0; -bool qt_resolveTextureFromPixmap() +static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice) { static bool resolvedTextureFromPixmap = false; @@ -1607,9 +1608,9 @@ bool qt_resolveTextureFromPixmap() { return false; // Can't use TFP without NPOT } - - QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); - if (glxExt.contains(QLatin1String("GLX_EXT_texture_from_pixmap"))) { + const QX11Info *xinfo = qt_x11Info(paintDevice); + QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(xinfo->display(), xinfo->screen())).split(' '); + if (glxExt.contains("GLX_EXT_texture_from_pixmap")) { glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT"); glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT"); } @@ -1630,7 +1631,7 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData *pmd, con Q_ASSERT(pmd->classId() == QPixmapData::X11Class); - if (!qt_resolveTextureFromPixmap()) + if (!qt_resolveTextureFromPixmap(paintDevice)) return 0; QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index aa6b6c9..8ab17a0 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -248,8 +248,8 @@ public: bound(false) { connect(QGLSignalProxy::instance(), - SIGNAL(aboutToDestroyContext(const QGLContext *)), - SLOT(cleanupGLContextRefs(const QGLContext *))); + SIGNAL(aboutToDestroyContext(const QGLContext*)), + SLOT(cleanupGLContextRefs(const QGLContext*))); } inline void setDevice(QPaintDevice *pdev); @@ -525,8 +525,8 @@ public: QGLProgramCache() { // we have to know when a context is deleted so we can free // any program handles it holds - connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext *)), - SLOT(cleanupPrograms(const QGLContext *))); + connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)), + SLOT(cleanupPrograms(const QGLContext*))); } ~QGLProgramCache() { @@ -639,8 +639,8 @@ public: : p(priv) { connect(QGLSignalProxy::instance(), - SIGNAL(aboutToDestroyContext(const QGLContext *)), - SLOT(cleanupGLContextRefs(const QGLContext *))); + SIGNAL(aboutToDestroyContext(const QGLContext*)), + SLOT(cleanupGLContextRefs(const QGLContext*))); } public Q_SLOTS: @@ -1010,8 +1010,8 @@ public: QGLGradientCache() : QObject(), buffer_ctx(0) { connect(QGLSignalProxy::instance(), - SIGNAL(aboutToDestroyContext(const QGLContext *)), - SLOT(cleanupGLContextRefs(const QGLContext *))); + SIGNAL(aboutToDestroyContext(const QGLContext*)), + SLOT(cleanupGLContextRefs(const QGLContext*))); } inline GLuint getBuffer(const QGradient &gradient, qreal opacity, QGLContext *ctx) { @@ -4712,8 +4712,8 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, const QTextItemInt &ti, 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 *))); + SIGNAL(aboutToDestroyContext(const QGLContext*)), + SLOT(cleanupContext(const QGLContext*))); } } else { font_cache = dev_it.value(); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index f1f5976..e353f5d 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -374,7 +374,7 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) union { QGLContext **ctxPtr; void **voidPtr; }; - connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(deleted(QObject *))); + connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(deleted(QObject*))); voidPtr = &widgetPrivate->extraData()->glContext; d_ptr->contexts << ctxPtr; |