diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-05-11 11:44:50 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-05-11 11:44:50 (GMT) |
commit | fd252f78e907bb998fc654c0332cfd2adfaf8b1e (patch) | |
tree | 4b09a528659361121e133c12e307bf27587efb9e /src/opengl | |
parent | b4c589868f278aa9a58ab9afa727dbf0a9442e22 (diff) | |
parent | a7b128ae838b006be1259ef6ba79da5440ed52dd (diff) | |
download | Qt-fd252f78e907bb998fc654c0332cfd2adfaf8b1e.zip Qt-fd252f78e907bb998fc654c0332cfd2adfaf8b1e.tar.gz Qt-fd252f78e907bb998fc654c0332cfd2adfaf8b1e.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2: (24 commits)
Stabilize tst_QColumnView::parentCurrentIndex
Really fix tst_QDockWidget::taskQTBUG_9758_undockedGeometry on Linux
Fix typos in Elastic Nodes example documentation.
Made paint engine texture drawing work in GL ES 2 and updated docs.
Opt out of visual-config size checks with extension
Fix off-by-one in text layouts and widget size hints on Mac
Stabilize tst_QDockWidget::taskQTBUG_9758_undockedGeometry
Mark QFileDialog::Options as a Q_FLAGS
fix tst_QDockWidget::taskQTBUG_9758_undockedGeometry on Linux
Fixed scrolling bugs in widget graphics effect backend.
Fixed source pixmap bug in widget graphics effect backend.
Fix crash with stylesheet if widget change style in the changeEvent
Fix textdrawing under GL on N900.
Fixed bug in QIODevice::read after first reading 0 bytes.
Fix auto-test failure on Mac/Linux/QWS.
Some EGL implementations does not return a EGLNativeDisplayType
Fixed the sizing of the dock area with fixed size dock widgets
QSortFilterProxyModel: Warning or assert failure
Performance issue with QGraphicsItem::ItemClipsChildrenToShape.
Fixes crash in QGraphicsItem::mouseMove for untransformable items.
...
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 86 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h | 5 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 73 |
3 files changed, 105 insertions, 59 deletions
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 994c1c9..452d37d 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -42,6 +42,10 @@ #include "qtextureglyphcache_gl_p.h" #include "qpaintengineex_opengl2_p.h" +#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL) +#include "private/qeglcontext_p.h" +#endif + QT_BEGIN_NAMESPACE #ifdef Q_WS_WIN @@ -49,12 +53,27 @@ extern Q_GUI_EXPORT bool qt_cleartype_enabled; #endif QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix) - : QTextureGlyphCache(type, matrix) + : QImageTextureGlyphCache(type, matrix) , ctx(context) , m_width(0) , m_height(0) + , m_broken_fbo_readback(false) { - glGenFramebuffers(1, &m_fbo); + // broken FBO readback is a bug in the SGX 1.3 and 1.4 drivers for the N900 where + // copying between FBO's is broken if the texture is either GL_ALPHA or POT. The + // workaround is to use a system-memory copy of the glyph cache for this device. + // Switching to NPOT and GL_RGBA would both cost a lot more graphics memory and + // be slower, so that is not desireable. +#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL) + if (QByteArray((char*) glGetString(GL_RENDERER)).contains("SGX")) { + QGLContextPrivate *ctxd = context->d_func(); + m_broken_fbo_readback = QByteArray((char *) eglQueryString(ctxd->eglContext->display(), EGL_VERSION)).contains("1.3"); + } +#endif + + if (!m_broken_fbo_readback) + glGenFramebuffers(1, &m_fbo); + connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)), SLOT(contextDestroyed(const QGLContext*))); } @@ -63,7 +82,9 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache() { if (ctx) { QGLShareContextScope scope(ctx); - glDeleteFramebuffers(1, &m_fbo); + + if (!m_broken_fbo_readback) + glDeleteFramebuffers(1, &m_fbo); if (m_width || m_height) glDeleteTextures(1, &m_texture); @@ -72,6 +93,12 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache() void QGLTextureGlyphCache::createTextureData(int width, int height) { + // create in QImageTextureGlyphCache baseclass is meant to be called + // only to create the initial image and does not preserve the content, + // so we don't call when this function is called from resize. + if (m_broken_fbo_readback && image().isNull()) + QImageTextureGlyphCache::createTextureData(width, height); + glGenTextures(1, &m_texture); glBindTexture(GL_TEXTURE_2D, m_texture); @@ -93,14 +120,22 @@ void QGLTextureGlyphCache::createTextureData(int width, int height) void QGLTextureGlyphCache::resizeTextureData(int width, int height) { - // ### the QTextureGlyphCache API needs to be reworked to allow - // ### resizeTextureData to fail - int oldWidth = m_width; int oldHeight = m_height; GLuint oldTexture = m_texture; createTextureData(width, height); + + if (m_broken_fbo_readback) { + QImageTextureGlyphCache::resizeTextureData(width, height); + Q_ASSERT(image().depth() == 8); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); + glDeleteTextures(1, &oldTexture); + return; + } + + // ### the QTextureGlyphCache API needs to be reworked to allow + // ### resizeTextureData to fail glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo); @@ -159,20 +194,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) glBindTexture(GL_TEXTURE_2D, m_texture); -#ifdef QT_OPENGL_ES_2 - QDataBuffer<uchar> buffer(4*oldWidth*oldHeight); - buffer.resize(4*oldWidth*oldHeight); - glReadPixels(0, 0, oldWidth, oldHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); - - // do an in-place conversion from GL_RGBA to GL_ALPHA - for (int i=0; i<oldWidth*oldHeight; ++i) - buffer.data()[i] = buffer.at(4*i + 3); - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, - GL_ALPHA, GL_UNSIGNED_BYTE, buffer.data()); -#else glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); -#endif glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, 0); @@ -187,6 +209,21 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) { + if (m_broken_fbo_readback) { + QImageTextureGlyphCache::fillTexture(c, glyph); + + glBindTexture(GL_TEXTURE_2D, m_texture); + const QImage &texture = image(); + const uchar *bits = texture.constBits(); + bits += c.y * texture.bytesPerLine() + c.x; + for (int i=0; i<c.h; ++i) { + glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits); + bits += texture.bytesPerLine(); + } + + return; + } + QImage mask = textureMapForGlyph(glyph); const int maskWidth = mask.width(); const int maskHeight = mask.height(); @@ -235,17 +272,6 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) } } -int QGLTextureGlyphCache::glyphMargin() const -{ -#if defined(Q_WS_MAC) - return 2; -#elif defined (Q_WS_X11) - return 0; -#else - return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0; -#endif -} - int QGLTextureGlyphCache::glyphPadding() const { return 1; diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h index 75c2bb1..efb7435 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE class QGL2PaintEngineExPrivate; -class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QTextureGlyphCache +class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QObject, public QImageTextureGlyphCache { Q_OBJECT public: @@ -72,7 +72,6 @@ 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 int glyphMargin() const; virtual int glyphPadding() const; inline GLuint texture() const { return m_texture; } @@ -116,6 +115,8 @@ private: int m_height; QGLShaderProgram *m_program; + + bool m_broken_fbo_readback; }; QT_END_NAMESPACE diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index cfacf26..a3c1bac 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2773,23 +2773,27 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex /*! \since 4.4 - Draws the given texture, \a textureId, to the given target rectangle, - \a target, in OpenGL model space. The \a textureTarget should be a 2D - texture target. + This function supports the following use cases: + + \list + \i On OpenGL and OpenGL ES 1.x it draws the given texture, \a textureId, + to the given target rectangle, \a target, in OpenGL model space. The + \a textureTarget should be a 2D texture target. + \i On OpenGL and OpenGL ES 2.x, if a painter is active, not inside a + beginNativePainting / endNativePainting block, and uses the + engine with type QPaintEngine::OpenGL2, the function will draw the given + texture, \a textureId, to the given target rectangle, \a target, + respecting the current painter state. This will let you draw a texture + with the clip, transform, render hints, and composition mode set by the + painter. Note that the texture target needs to be GL_TEXTURE_2D for this + use case, and that this is the only supported use case under OpenGL ES 2.x. + \endlist - \note This function is not supported under OpenGL/ES 2.0. */ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) { -#ifndef QT_OPENGL_ES_2 -#ifdef QT_OPENGL_ES - if (textureTarget != GL_TEXTURE_2D) { - qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); - return; - } -#else - - if (d_ptr->active_engine && +#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) + if (d_ptr->active_engine && d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine); if (!eng->isNativePaintingActive()) { @@ -2799,7 +2803,15 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text return; } } +#endif +#ifndef QT_OPENGL_ES_2 +#ifdef QT_OPENGL_ES + if (textureTarget != GL_TEXTURE_2D) { + qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); + return; + } +#else const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); GLint oldTexture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); @@ -2821,7 +2833,7 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text Q_UNUSED(target); Q_UNUSED(textureId); Q_UNUSED(textureTarget); - qWarning("drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES/2.0"); + qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine"); #endif } @@ -2836,14 +2848,26 @@ void QGLContext::drawTexture(const QRectF &target, QMacCompatGLuint textureId, Q /*! \since 4.4 - Draws the given texture at the given \a point in OpenGL model - space. The \a textureTarget should be a 2D texture target. + This function supports the following use cases: + + \list + \i By default it draws the given texture, \a textureId, + at the given \a point in OpenGL model space. The + \a textureTarget should be a 2D texture target. + \i If a painter is active, not inside a + beginNativePainting / endNativePainting block, and uses the + engine with type QPaintEngine::OpenGL2, the function will draw the given + texture, \a textureId, at the given \a point, + respecting the current painter state. This will let you draw a texture + with the clip, transform, render hints, and composition mode set by the + painter. Note that the texture target needs to be GL_TEXTURE_2D for this + use case. + \endlist - \note This function is not supported under OpenGL/ES. + \note This function is not supported under any version of OpenGL ES. */ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) { - // this would be ok on OpenGL ES 2.0, but currently we don't have a define for that #ifdef QT_OPENGL_ES Q_UNUSED(point); Q_UNUSED(textureId); @@ -4911,11 +4935,8 @@ void QGLWidget::deleteTexture(QMacCompatGLuint id) /*! \since 4.4 - Draws the given texture, \a textureId to the given target rectangle, - \a target, in OpenGL model space. The \a textureTarget should be a 2D - texture target. - - Equivalent to the corresponding QGLContext::drawTexture(). + Calls the corresponding QGLContext::drawTexture() on + this widget's context. */ void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) { @@ -4935,10 +4956,8 @@ void QGLWidget::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QM /*! \since 4.4 - Draws the given texture, \a textureId, at the given \a point in OpenGL - model space. The \a textureTarget should be a 2D texture target. - - Equivalent to the corresponding QGLContext::drawTexture(). + Calls the corresponding QGLContext::drawTexture() on + this widget's context. */ void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) { |