diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2010-04-21 12:22:24 (GMT) |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2010-04-21 12:22:24 (GMT) |
commit | 51dca5f8afc3aa619a3bb62858db78a85cc3ecef (patch) | |
tree | dfc1fb65b6a8e5e429f1701992548f8a0425decb /src/opengl | |
parent | 6f5ad5dcab8e6f702894c4fa5c016d9837375626 (diff) | |
parent | c74dac2a0ef5d1b428c4da4e48fab05f9886233a (diff) | |
download | Qt-51dca5f8afc3aa619a3bb62858db78a85cc3ecef.zip Qt-51dca5f8afc3aa619a3bb62858db78a85cc3ecef.tar.gz Qt-51dca5f8afc3aa619a3bb62858db78a85cc3ecef.tar.bz2 |
Merge remote branch 'origin/4.7' into lighthouse
Conflicts:
configure
src/gui/kernel/qapplication.cpp
src/gui/painting/qbackingstore.cpp
src/opengl/qgl.cpp
src/opengl/qgl_p.h
src/plugins/plugins.pro
tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir
tools/tools.pro
Diffstat (limited to 'src/opengl')
23 files changed, 381 insertions, 143 deletions
diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index d1e7615..adc69ee 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -132,6 +132,11 @@ public: } + inline void addVertex(const GLfloat x, const GLfloat y) + { + vertexArray.add(QGLPoint(x, y)); + } + void addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline = true); void clear(); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index b90f0c2..c89d34f 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -191,7 +191,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() QImage texImage = qt_imageForBrush(style, false); glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, true, QGLContext::InternalBindOption); + ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); } else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) { @@ -217,7 +217,9 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() const QPixmap& texPixmap = currentBrush.texture(); glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - QGLTexture *tex = ctx->d_func()->bindTexture(texPixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption); + QGLTexture *tex = ctx->d_func()->bindTexture(texPixmap, GL_TEXTURE_2D, GL_RGBA, + QGLContext::InternalBindOption | + QGLContext::CanFlipNativePixmapBindOption); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); textureInvertedY = tex->options & QGLContext::InvertedYBindOption ? -1 : 1; } @@ -514,6 +516,8 @@ void QGL2PaintEngineEx::beginNativePainting() ensureActive(); d->transferMode(BrushDrawingMode); + d->nativePaintingActive = true; + QGLContext *ctx = d->ctx; glUseProgram(0); @@ -529,10 +533,10 @@ void QGL2PaintEngineEx::beginNativePainting() float mv_matrix[4][4] = { - { mtx.m11(), mtx.m12(), 0, mtx.m13() }, - { mtx.m21(), mtx.m22(), 0, mtx.m23() }, - { 0, 0, 1, 0 }, - { mtx.dx(), mtx.dy(), 0, mtx.m33() } + { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) }, + { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) }, + { 0, 0, 1, 0 }, + { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) } }; const QSize sz = d->device->size(); @@ -581,6 +585,12 @@ void QGL2PaintEngineEx::endNativePainting() { Q_D(QGL2PaintEngineEx); d->needsSync = true; + d->nativePaintingActive = false; +} + +bool QGL2PaintEngineEx::isNativePaintingActive() const { + Q_D(const QGL2PaintEngineEx); + return d->nativePaintingActive; } void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) @@ -1641,7 +1651,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp glBindTexture(GL_TEXTURE_2D, cache->texture()); lastMaskTextureUsed = cache->texture(); } - updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); + updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, s->matrix.type() > QTransform::TxTranslate); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::MaskTexture), QT_MASK_TEXTURE_UNIT); #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) @@ -1706,23 +1716,23 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragmen QGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c); QGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c); - vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); - vertexCoordinateArray.lineToArray(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y); - vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); - vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); - vertexCoordinateArray.lineToArray(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y); - vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y); + vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); + vertexCoordinateArray.addVertex(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y); + vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); QGLRect src(fragments[i].sourceLeft * dx, fragments[i].sourceTop * dy, (fragments[i].sourceLeft + fragments[i].width) * dx, (fragments[i].sourceTop + fragments[i].height) * dy); - textureCoordinateArray.lineToArray(src.right, src.bottom); - textureCoordinateArray.lineToArray(src.right, src.top); - textureCoordinateArray.lineToArray(src.left, src.top); - textureCoordinateArray.lineToArray(src.left, src.top); - textureCoordinateArray.lineToArray(src.left, src.bottom); - textureCoordinateArray.lineToArray(src.right, src.bottom); + textureCoordinateArray.addVertex(src.right, src.bottom); + textureCoordinateArray.addVertex(src.right, src.top); + textureCoordinateArray.addVertex(src.left, src.top); + textureCoordinateArray.addVertex(src.left, src.top); + textureCoordinateArray.addVertex(src.left, src.bottom); + textureCoordinateArray.addVertex(src.right, src.bottom); qreal opacity = fragments[i].opacity * q->state()->opacity; opacityArray << opacity << opacity << opacity << opacity << opacity << opacity; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 34d72d1..2ac2ca4 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -154,11 +154,11 @@ public: void setRenderTextActive(bool); + bool isNativePaintingActive() const; private: Q_DISABLE_COPY(QGL2PaintEngineEx) }; - class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate { Q_DECLARE_PUBLIC(QGL2PaintEngineEx) @@ -178,6 +178,7 @@ public: elementIndicesVBOId(0), snapToPixelGrid(false), addOffset(false), + nativePaintingActive(false), inverseScale(1), lastMaskTextureUsed(0) { } @@ -280,6 +281,7 @@ public: bool snapToPixelGrid; bool addOffset; // When enabled, adds a 0.49,0.49 offset to matrix in updateMatrix + bool nativePaintingActive; GLfloat pmvMatrix[3][3]; GLfloat inverseScale; diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 6cb76ee..994c1c9 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -246,4 +246,9 @@ int QGLTextureGlyphCache::glyphMargin() const #endif } +int QGLTextureGlyphCache::glyphPadding() const +{ + return 1; +} + QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h index 2a8a782..04731b1 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h @@ -73,6 +73,7 @@ public: 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; } diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index d952988..f677ce1 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -111,7 +111,7 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, co // depending on if the pen is cosmetic or not. // // The curvyness value of PI/14 was based on, - // arcLength=2*PI*r/4=PI/2 and splitting length into somewhere + // arcLength = 2*PI*r/4 = PI*r/2 and splitting length into somewhere // between 3 and 8 where 5 seemed to be give pretty good results // hence: Q_PI/14. Lower divisors will give more detail at the // direct cost of performance. @@ -144,11 +144,17 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, co m_cos_theta = qFastCos(Q_PI / m_roundness); const qreal *endPts = pts + (count<<1); - const qreal *startPts; + const qreal *startPts = 0; Qt::PenCapStyle cap = m_cap_style; if (!types) { + // skip duplicate points + while((pts + 2) < endPts && pts[0] == pts[2] && pts[1] == pts[3]) + pts += 2; + if ((pts + 2) == endPts) + return; + startPts = pts; bool endsAtStart = startPts[0] == *(endPts-2) && startPts[1] == *(endPts-1); @@ -161,15 +167,17 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, co lineTo(pts); pts += 2; while (pts < endPts) { - join(pts); - lineTo(pts); + if (m_cx != pts[0] || m_cy != pts[1]) { + join(pts); + lineTo(pts); + } pts += 2; } endCapOrJoinClosed(startPts, pts-2, path.hasImplicitClose(), endsAtStart); } else { - bool endsAtStart; + bool endsAtStart = false; while (pts < endPts) { switch (*types) { case QPainterPath::MoveToElement: { @@ -487,6 +495,8 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c const QPainterPath::ElementType *types = path.elements(); int count = path.elementCount(); + bool cosmetic = pen.isCosmetic(); + m_points.reset(); m_types.reset(); @@ -495,10 +505,26 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c width = 1; m_dash_stroker.setDashPattern(pen.dashPattern()); - m_dash_stroker.setStrokeWidth(pen.isCosmetic() ? width * m_inv_scale : width); + m_dash_stroker.setStrokeWidth(cosmetic ? width * m_inv_scale : width); m_dash_stroker.setMiterLimit(pen.miterLimit()); m_dash_stroker.setClipRect(clip); - qreal curvyness = sqrt(width) * m_inv_scale / 8; + + float curvynessAdd, curvynessMul, roundness = 0; + + // simplfy pens that are thin in device size (2px wide or less) + if (width < 2.5 && (cosmetic || m_inv_scale == 1)) { + curvynessAdd = 0.5; + curvynessMul = CURVE_FLATNESS / m_inv_scale; + roundness = 1; + } else if (cosmetic) { + curvynessAdd= width / 2; + curvynessMul= CURVE_FLATNESS; + roundness = qMax<int>(4, width * CURVE_FLATNESS); + } else { + curvynessAdd = width * m_inv_scale; + curvynessMul = CURVE_FLATNESS / m_inv_scale; + roundness = qMax<int>(4, width * curvynessMul); + } if (count < 2) return; @@ -533,9 +559,11 @@ void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, c *(((const QPointF *) pts) + 1), *(((const QPointF *) pts) + 2)); QRectF bounds = b.bounds(); - int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * curvyness); + float rad = qMax(bounds.width(), bounds.height()); + int threshold = qMin<float>(64, (rad + curvynessAdd) * curvynessMul); if (threshold < 4) threshold = 4; + qreal threshold_minus_1 = threshold - 1; for (int i=0; i<threshold; ++i) { QPointF pt = b.pointAt(i / threshold_minus_1); diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 42608e3..6eb4ebe 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -90,7 +90,7 @@ embedded_lite { } x11 { - contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) { + contains(QT_CONFIG, egl) { SOURCES += qgl_x11egl.cpp \ qglpixelbuffer_egl.cpp \ qgl_egl.cpp \ @@ -129,6 +129,7 @@ mac { LIBS_PRIVATE += -framework AppKit -framework Carbon } win32:!wince*: { + DEFINES += QT_NO_EGL SOURCES += qgl_win.cpp \ qglpixelbuffer_win.cpp } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 6c6f6d9..580f3d0 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -49,7 +49,7 @@ #include "private/qpixmap_x11_p.h" #define INT32 dummy_INT32 #define INT8 dummy_INT8 -#if !defined(QT_OPENGL_ES) +#ifdef QT_NO_EGL # include <GL/glx.h> #endif #undef INT32 @@ -1588,7 +1588,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) #endif #if defined(Q_WS_LITE) platformContext = 0; -#elif defined(QT_OPENGL_ES) +#elif !defined(QT_NO_EGL) ownsEglContext = false; eglContext = 0; eglSurface = EGL_NO_SURFACE; @@ -2214,8 +2214,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G Q_Q(QGLContext); #ifdef QGL_BIND_TEXTURE_DEBUG - printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x\n", - image.width(), image.height(), internalFormat, int(options)); + printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x, key=%llx\n", + image.width(), image.height(), internalFormat, int(options), key); QTime time; time.start(); #endif @@ -2448,9 +2448,10 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, // Try to use texture_from_pixmap const QX11Info *xinfo = qt_x11Info(paintDevice); if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType - && xinfo && xinfo->screen() == pixmap.x11Info().screen()) + && xinfo && xinfo->screen() == pixmap.x11Info().screen() + && target == GL_TEXTURE_2D) { - texture = bindTextureFromNativePixmap(pd, key, options); + texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options); if (texture) { texture->options |= QGLContext::MemoryManagedBindOption; texture->boundPixmap = pd; @@ -2459,8 +2460,15 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, } #endif - if (!texture) - texture = bindTexture(pixmap.toImage(), target, format, key, options); + if (!texture) { + QImage image = pixmap.toImage(); + // If the system depth is 16 and the pixmap doesn't have an alpha channel + // then we convert it to RGB16 in the hope that it gets uploaded as a 16 + // bit texture which is much faster to access than a 32-bit one. + if (pixmap.depth() == 16 && !image.hasAlphaChannel() ) + image = image.convertToFormat(QImage::Format_RGB16); + texture = bindTexture(image, target, format, key, options); + } // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null Q_ASSERT(texture); @@ -2553,7 +2561,7 @@ GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format, return 0; Q_D(QGLContext); - QGLTexture *texture = d->bindTexture(image, target, format, false, options); + QGLTexture *texture = d->bindTexture(image, target, format, options); return texture->id; } @@ -2565,7 +2573,7 @@ GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMa return 0; Q_D(QGLContext); - QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false, DefaultBindOption); + QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), DefaultBindOption); return texture->id; } @@ -2577,7 +2585,7 @@ GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMa return 0; Q_D(QGLContext); - QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false, options); + QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), options); return texture->id; } #endif @@ -2765,6 +2773,18 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text return; } #else + + if (d_ptr->active_engine && + d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { + QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine); + if (!eng->isNativePaintingActive()) { + QRectF src(0, 0, target.width(), target.height()); + QSize size(target.width(), target.height()); + eng->drawTexture(target, textureId, size, src); + return; + } + } + const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); GLint oldTexture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); @@ -2815,6 +2835,7 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text Q_UNUSED(textureTarget); qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead"); #else + const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); GLint oldTexture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); @@ -2828,6 +2849,18 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); + if (d_ptr->active_engine && + d_ptr->active_engine->type() == QPaintEngine::OpenGL2) { + QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine); + if (!eng->isNativePaintingActive()) { + QRectF dest(point, QSizeF(textureWidth, textureHeight)); + QRectF src(0, 0, textureWidth, textureHeight); + QSize size(textureWidth, textureHeight); + eng->drawTexture(dest, textureId, size, src); + return; + } + } + qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget); if (!wasEnabled) @@ -3948,7 +3981,7 @@ bool QGLWidget::event(QEvent *e) } } -#if defined(QT_OPENGL_ES) +#ifndef QT_NO_EGL // A re-parent is likely to destroy the X11 window and re-create it. It is important // that we free the EGL surface _before_ the winID changes - otherwise we can leak. if (e->type() == QEvent::ParentAboutToChange) @@ -4907,7 +4940,7 @@ void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QM } #endif -#if !defined(QT_OPENGL_ES_1) +#ifndef QT_OPENGL_ES_1 Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine) #endif diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 64f54a3..b1e2ede 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -376,7 +376,7 @@ protected: #if defined(Q_WS_WIN) virtual int choosePixelFormat(void* pfd, HDC pdc); #endif -#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES) +#if defined(Q_WS_X11) && defined(QT_NO_EGL) virtual void* tryVisual(const QGLFormat& f, int bufDepth = 1); virtual void* chooseVisual(); #endif diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 822c9f6..0fbbbf9 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -147,7 +147,7 @@ void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config) // Clear the EGL error state because some of the above may // have errored out because the attribute is not applicable // to the surface type. Such errors don't matter. - QEgl::clearError(); + eglGetError(); } bool QGLFormat::hasOpenGL() diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h index 43793cd..85d7f32 100644 --- a/src/opengl/qgl_egl_p.h +++ b/src/opengl/qgl_egl_p.h @@ -53,6 +53,7 @@ // We mean it. // +#include <QtGui/private/qegl_p.h> #include <QtGui/private/qeglcontext_p.h> #include <QtGui/private/qeglproperties_p.h> diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 6405a54..c7cd3fe 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -64,7 +64,7 @@ #include "qcache.h" #include "qglpaintdevice_p.h" -#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) +#ifndef QT_NO_EGL #include <QtGui/private/qegl_p.h> #endif @@ -100,7 +100,7 @@ class QMacWindowChangeEvent; class QWSGLWindowSurface; #endif -#if defined(QT_OPENGL_ES) +#ifndef QT_NO_EGL class QEglContext; #endif @@ -168,7 +168,7 @@ public: #ifdef Q_WS_QWS , wsurf(0) #endif -#if defined(Q_WS_X11) && defined(QT_OPENGL_ES) +#if defined(Q_WS_X11) && !defined(QT_NO_EGL) , eglSurfaceWindowId(0) #endif { @@ -198,7 +198,7 @@ public: QGLContext *olcx; #elif defined(Q_WS_X11) QGLOverlayWidget *olw; -#if defined(QT_OPENGL_ES) +#ifndef QT_NO_EGL void recreateEglSurface(bool force); WId eglSurfaceWindowId; #endif @@ -350,7 +350,7 @@ public: #endif #if defined(Q_WS_LITE) QPlatformGLContext *platformContext; -#elif defined(QT_OPENGL_ES) +#elif !defined(QT_NO_EGL) bool ownsEglContext; QEglContext *eglContext; EGLSurface eglSurface; @@ -367,7 +367,7 @@ public: quint32 gpm; int screen; QHash<QPixmapData*, QPixmap> boundPixmaps; - QGLTexture *bindTextureFromNativePixmap(QPixmapData*, const qint64 key, + QGLTexture *bindTextureFromNativePixmap(QPixmap*, const qint64 key, QGLContext::BindOptions options); static void destroyGlSurfaceForPixmap(QPixmapData*); static void unbindPixmapFromTexture(QPixmapData*); @@ -599,7 +599,7 @@ inline GLenum qt_gl_preferredTextureTarget() } // One resource per group of shared contexts. -class Q_AUTOTEST_EXPORT QGLContextResource +class Q_OPENGL_EXPORT QGLContextResource { public: typedef void (*FreeFunc)(void *); diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 4fa1467..d203646 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -1671,20 +1671,28 @@ static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice) #endif //defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) -QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData *pmd, const qint64 key, +QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key, QGLContext::BindOptions options) { #if !defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX) return 0; #else + + // Check we have GLX 1.3, as it is needed for glXCreatePixmap & glXDestroyPixmap + int majorVersion = 0; + int minorVersion = 0; + glXQueryVersion(X11->display, &majorVersion, &minorVersion); + if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 3)) + return 0; + Q_Q(QGLContext); - Q_ASSERT(pmd->classId() == QPixmapData::X11Class); + QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data()); + Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); if (!qt_resolveTextureFromPixmap(paintDevice)) return 0; - QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); const QX11Info &x11Info = pixmapData->xinfo; // Store the configs (Can be static because configs aren't dependent on current context) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 0954e69..d67a3ea 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -199,6 +199,10 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) configProps.setRenderableType(QEgl::OpenGL); qt_eglproperties_set_glformat(configProps, d->glFormat); + // Set buffer preserved for regular QWidgets, QGLWidgets are ok with either preserved or destroyed: + if ((devType == QInternal::Widget) && qobject_cast<QGLWidget*>(static_cast<QWidget*>(device())) == 0) + configProps.setValue(EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); + if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { delete d->eglContext; d->eglContext = 0; @@ -354,7 +358,7 @@ void QGLWidgetPrivate::recreateEglSurface(bool force) } -QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, const qint64 key, +QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key, QGLContext::BindOptions options) { Q_Q(QGLContext); @@ -363,10 +367,31 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons if (!(options & QGLContext::CanFlipNativePixmapBindOption)) return 0; - Q_ASSERT(pd->classId() == QPixmapData::X11Class); static bool checkedForTFP = false; static bool haveTFP = false; + static bool checkedForEglImageTFP = false; + static bool haveEglImageTFP = false; + + + if (!checkedForEglImageTFP) { + checkedForEglImageTFP = true; + + // We need to be able to create an EGLImage from a native pixmap, which was split + // into a seperate EGL extension, EGL_KHR_image_pixmap. It is possible to have + // eglCreateImageKHR & eglDestroyImageKHR without support for pixmaps, so we must + // check we have the EGLImage from pixmap functionality. + if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) { + + // Being able to create an EGLImage from a native pixmap is also pretty useless + // without the ability to bind that EGLImage as a texture, which is provided by + // the GL_OES_EGL_image extension, which we try to resolve here: + haveEglImageTFP = qt_resolve_eglimage_gl_extensions(q); + + if (haveEglImageTFP) + qDebug("Found EGL_KHR_image_pixmap & GL_OES_EGL_image extensions (preferred method)!"); + } + } if (!checkedForTFP) { // Check for texture_from_pixmap egl extension @@ -379,61 +404,109 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons } } - if (!haveTFP) + if (!haveTFP && !haveEglImageTFP) return 0; - QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pd); + QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data()); + Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); bool hasAlpha = pixmapData->hasAlphaChannel(); + bool pixmapHasValidSurface = false; + bool textureIsBound = false; + GLuint textureId; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); - // Check to see if the surface is still valid - if (pixmapData->gl_surface && - hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) + if (haveTFP && pixmapData->gl_surface && + hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) { - // Surface is invalid! - destroyGlSurfaceForPixmap(pixmapData); + pixmapHasValidSurface = true; } - if (pixmapData->gl_surface == 0) { - EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap, - QEgl::OpenGL, - hasAlpha ? QEgl::Translucent : QEgl::NoOptions); + // If we already have a valid EGL surface for the pixmap, we should use it + if (pixmapHasValidSurface) { + EGLBoolean success; + success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); + if (success == EGL_FALSE) { + qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); + eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); + pixmapData->gl_surface = (void*)EGL_NO_SURFACE; + } else + textureIsBound = true; + } - QPixmap tmpPixmap(pixmapData); //### - pixmapData->gl_surface = (void*)QEgl::createSurface(&tmpPixmap, config); - if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) { - haveTFP = false; - return 0; - } + // If the pixmap doesn't already have a valid surface, try binding it via EGLImage + // first, as going through EGLImage should be faster and better supported: + if (!textureIsBound && haveEglImageTFP) { + EGLImageKHR eglImage; + + EGLint attribs[] = { + EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, + EGL_NONE + }; + eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer)QEgl::nativePixmap(pixmap), attribs); + + QGLContext* ctx = q; + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage); + + GLint err = glGetError(); + if (err == GL_NO_ERROR) + textureIsBound = true; + + // Once the egl image is bound, the texture becomes a new sibling image and we can safely + // destroy the EGLImage we created for the pixmap: + if (eglImage != EGL_NO_IMAGE_KHR) + QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); } - Q_ASSERT(pixmapData->gl_surface); + if (!textureIsBound && haveTFP) { + // Check to see if the surface is still valid + if (pixmapData->gl_surface && + hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) + { + // Surface is invalid! + destroyGlSurfaceForPixmap(pixmapData); + } - GLuint textureId; - glGenTextures(1, &textureId); - glBindTexture(GL_TEXTURE_2D, textureId); + if (pixmapData->gl_surface == 0) { + EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap, + QEgl::OpenGL, + hasAlpha ? QEgl::Translucent : QEgl::NoOptions); - // bind the egl pixmap surface to a texture - EGLBoolean success; - success = eglBindTexImage(eglContext->display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); - if (success == EGL_FALSE) { - qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); - eglDestroySurface(eglContext->display(), (EGLSurface)pixmapData->gl_surface); - pixmapData->gl_surface = (void*)EGL_NO_SURFACE; - haveTFP = false; - return 0; + pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config); + if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) + return false; + } + + EGLBoolean success; + success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); + if (success == EGL_FALSE) { + qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); + eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); + pixmapData->gl_surface = (void*)EGL_NO_SURFACE; + haveTFP = false; // If TFP isn't working, disable it's use + } else + textureIsBound = true; } - QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options); - pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture; + QGLTexture *texture = 0; - // We assume the cost of bound pixmaps is zero - QGLTextureCache::instance()->insert(q, key, texture, 0); + if (textureIsBound) { + texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options); + pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture; + + // We assume the cost of bound pixmaps is zero + QGLTextureCache::instance()->insert(q, key, texture, 0); + + glBindTexture(GL_TEXTURE_2D, textureId); + } else + glDeleteTextures(1, &textureId); - glBindTexture(GL_TEXTURE_2D, textureId); return texture; } + void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd) { Q_ASSERT(pmd->classId() == QPixmapData::X11Class); diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp index 2ab7c32..223243c 100644 --- a/src/opengl/qglbuffer.cpp +++ b/src/opengl/qglbuffer.cpp @@ -289,6 +289,10 @@ bool QGLBuffer::read(int offset, void *data, int count) */ void QGLBuffer::write(int offset, const void *data, int count) { +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::allocate(): buffer not created"); +#endif Q_D(QGLBuffer); if (d->guard.id()) glBufferSubData(d->type, offset, count, data); @@ -305,6 +309,10 @@ void QGLBuffer::write(int offset, const void *data, int count) */ void QGLBuffer::allocate(const void *data, int count) { +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::allocate(): buffer not created"); +#endif Q_D(QGLBuffer); if (d->guard.id()) glBufferData(d->type, count, data, d->actualUsagePattern); @@ -336,6 +344,10 @@ void QGLBuffer::allocate(const void *data, int count) */ bool QGLBuffer::bind() const { +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::bind(): buffer not created"); +#endif Q_D(const QGLBuffer); GLuint bufferId = d->guard.id(); if (bufferId) { @@ -364,6 +376,10 @@ bool QGLBuffer::bind() const */ void QGLBuffer::release() const { +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::release(): buffer not created"); +#endif Q_D(const QGLBuffer); if (d->guard.id()) glBindBuffer(d->type, 0); @@ -372,31 +388,23 @@ void QGLBuffer::release() const #undef ctx /*! - Binds a raw \a bufferId to the specified buffer \a type - in the current QGLContext. Returns false if there is - no context current or the GL buffer extension could - not be resolved. + Releases the buffer associated with \a type in the current + QGLContext. - This function is a direct call to \c{glBindBuffer()} for - use when the caller does not have a QGLBuffer but does - have a raw \a bufferId. It can also be used to release - the current buffer when the caller does not know which - QGLBuffer object is currently bound: + This function is a direct call to \c{glBindBuffer(type, 0)} + for use when the caller does not know which QGLBuffer has + been bound to the context but wants to make sure that it + is released. \code - QGLBuffer::bind(QGLBuffer::VertexBuffer, 0); + QGLBuffer::release(QGLBuffer::VertexBuffer); \endcode */ -bool QGLBuffer::bind(QGLBuffer::Type type, uint bufferId) +void QGLBuffer::release(QGLBuffer::Type type) { const QGLContext *ctx = QGLContext::currentContext(); - if (ctx) { - if (qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx))) { - glBindBuffer(GLenum(type), GLuint(bufferId)); - return true; - } - } - return false; + if (ctx && qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx))) + glBindBuffer(GLenum(type), 0); } #define ctx d->guard.context() @@ -407,7 +415,7 @@ bool QGLBuffer::bind(QGLBuffer::Type type, uint bufferId) \sa isCreated() */ -uint QGLBuffer::bufferId() const +GLuint QGLBuffer::bufferId() const { Q_D(const QGLBuffer); return d->guard.id(); @@ -453,6 +461,10 @@ int QGLBuffer::size() const void *QGLBuffer::map(QGLBuffer::Access access) { Q_D(QGLBuffer); +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::map(): buffer not created"); +#endif if (!d->guard.id()) return 0; if (!glMapBufferARB) @@ -476,6 +488,10 @@ void *QGLBuffer::map(QGLBuffer::Access access) bool QGLBuffer::unmap() { Q_D(QGLBuffer); +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QGLBuffer::unmap(): buffer not created"); +#endif if (!d->guard.id()) return false; if (!glUnmapBufferARB) diff --git a/src/opengl/qglbuffer.h b/src/opengl/qglbuffer.h index a060733..2fe1f1f 100644 --- a/src/opengl/qglbuffer.h +++ b/src/opengl/qglbuffer.h @@ -43,6 +43,7 @@ #define QGLBUFFER_H #include <QtCore/qscopedpointer.h> +#include <QtOpenGL/qgl.h> QT_BEGIN_HEADER @@ -97,9 +98,9 @@ public: bool bind() const; void release() const; - static bool bind(QGLBuffer::Type type, uint bufferId); + static void release(QGLBuffer::Type type); - uint bufferId() const; + GLuint bufferId() const; int size() const; diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp index 02d5501..ef3c4cd 100644 --- a/src/opengl/qglextensions.cpp +++ b/src/opengl/qglextensions.cpp @@ -222,6 +222,17 @@ bool qt_resolve_buffer_extensions(QGLContext *ctx) #endif } +#ifndef QT_NO_EGL +bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx) +{ + if (glEGLImageTargetTexture2DOES || glEGLImageTargetRenderbufferStorageOES) + return true; + glEGLImageTargetTexture2DOES = (_glEGLImageTargetTexture2DOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetTexture2DOES")); + glEGLImageTargetRenderbufferStorageOES = (_glEGLImageTargetRenderbufferStorageOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetRenderbufferStorageOES")); + return glEGLImageTargetTexture2DOES && glEGLImageTargetRenderbufferStorageOES; +} +#endif + bool qt_resolve_glsl_extensions(QGLContext *ctx) { // Geometry shaders are optional... diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index f6926f3..7597b33 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -68,6 +68,11 @@ # define APIENTRYP * #endif +#ifndef QT_NO_EGL +// Needed for EGLImageKHR definition: +#include <QtGui/private/qegl_p.h> +#endif + #include <QtCore/qglobal.h> #ifndef GL_ARB_vertex_buffer_object @@ -210,6 +215,14 @@ typedef void (APIENTRY *_glFramebufferTextureFaceEXT)(GLenum target, GLenum atta typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +#ifndef QT_NO_EGL +// OES_EGL_image +// Note: We define these to take EGLImage whereas spec says they take a new GLeglImageOES +// type, which the EGL image should be cast to. +typedef void (APIENTRY *_glEGLImageTargetTexture2DOES) (GLenum, EGLImageKHR); +typedef void (APIENTRY *_glEGLImageTargetRenderbufferStorageOES) (GLenum, EGLImageKHR); +#endif + QT_BEGIN_NAMESPACE struct QGLExtensionFuncs @@ -327,6 +340,12 @@ struct QGLExtensionFuncs // Texture compression qt_glCompressedTexImage2DARB = 0; #endif + +#ifndef QT_NO_EGL + // OES_EGL_image + qt_glEGLImageTargetTexture2DOES = 0; + qt_glEGLImageTargetRenderbufferStorageOES = 0; +#endif } @@ -447,6 +466,13 @@ struct QGLExtensionFuncs // Texture compression _glCompressedTexImage2DARB qt_glCompressedTexImage2DARB; #endif + +#ifndef QT_NO_EGL + // OES_EGL_image + _glEGLImageTargetTexture2DOES qt_glEGLImageTargetTexture2DOES; + _glEGLImageTargetRenderbufferStorageOES qt_glEGLImageTargetRenderbufferStorageOES; +#endif + }; @@ -839,6 +865,12 @@ struct QGLExtensionFuncs #define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB #endif +#ifndef QT_NO_EGL +// OES_EGL_image +#define glEGLImageTargetTexture2DOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetTexture2DOES +#define glEGLImageTargetRenderbufferStorageOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetRenderbufferStorageOES +#endif + extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx); bool qt_resolve_buffer_extensions(QGLContext *ctx); @@ -849,6 +881,10 @@ bool qt_resolve_frag_program_extensions(QGLContext *ctx); bool qt_resolve_glsl_extensions(QGLContext *ctx); +#ifndef QT_NO_EGL +bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx); +#endif + QT_END_NAMESPACE #endif // QGL_EXTENSIONS_P_H diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index eca9550..9a8b243 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -137,14 +137,14 @@ void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &form #if defined(Q_WS_WIN) && !defined(QT_OPENGL_ES) qctx->d_func()->dc = dc; qctx->d_func()->rc = ctx; -#elif (defined(Q_WS_X11) && !defined(QT_OPENGL_ES)) +#elif (defined(Q_WS_X11) && defined(QT_NO_EGL)) qctx->d_func()->cx = ctx; qctx->d_func()->pbuf = (void *) pbuf; qctx->d_func()->vi = 0; #elif defined(Q_WS_MAC) qctx->d_func()->cx = ctx; qctx->d_func()->vi = 0; -#elif defined(QT_OPENGL_ES) +#elif !defined(QT_NO_EGL) qctx->d_func()->eglContext = ctx; qctx->d_func()->eglSurface = pbuf; #endif @@ -254,7 +254,7 @@ bool QGLPixelBuffer::doneCurrent() \sa size() */ -#if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && !defined(QT_OPENGL_ES) +#if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && defined(QT_NO_EGL) GLuint QGLPixelBuffer::generateDynamicTexture() const { Q_D(const QGLPixelBuffer); diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index db9e754..0b94f5a 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -75,9 +75,9 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge ctx->setConfig(shareContext->config()); #if QGL_RENDER_TEXTURE EGLint value = EGL_FALSE; - if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA, &value) && value) + if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA) == EGL_TRUE) textureFormat = EGL_TEXTURE_RGBA; - else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB, &value) && value) + else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB) == EGL_TRUE) textureFormat = EGL_TEXTURE_RGB; #endif } else { diff --git a/src/opengl/qglpixelbuffer_p.h b/src/opengl/qglpixelbuffer_p.h index bff35f5..de890c9 100644 --- a/src/opengl/qglpixelbuffer_p.h +++ b/src/opengl/qglpixelbuffer_p.h @@ -60,7 +60,7 @@ QT_BEGIN_INCLUDE_NAMESPACE #include <private/qgl_p.h> #include <private/qglpaintdevice_p.h> -#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES) +#if defined(Q_WS_X11) && defined(QT_NO_EGL) #include <GL/glx.h> // The below is needed to for compilation on HPUX, due to broken GLX @@ -127,10 +127,8 @@ struct GLXFBConfig { #elif defined(Q_WS_WIN) DECLARE_HANDLE(HPBUFFERARB); -#elif defined(QT_OPENGL_ES_2) -#include <EGL/egl.h> -#elif defined(QT_OPENGL_ES) -#include <GLES/egl.h> +#elif !defined(QT_NO_EGL) +#include <QtGui/private/qegl_p.h> #endif QT_END_INCLUDE_NAMESPACE @@ -174,7 +172,7 @@ public: QPointer<QGLWidget> req_shareWidget; QSize req_size; -#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES) +#if defined(Q_WS_X11) && defined(QT_NO_EGL) GLXPbuffer pbuf; GLXContext ctx; #elif defined(Q_WS_WIN) @@ -195,7 +193,7 @@ public: AGLContext share_ctx; # endif #endif -#if defined(QT_OPENGL_ES) +#ifndef QT_NO_EGL EGLSurface pbuf; QEglContext *ctx; int textureFormat; diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 739983e..83b4b21 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -999,17 +999,18 @@ GLuint QGLShaderProgram::programId() const Any attributes that have not been explicitly bound when the program is linked will be assigned locations automatically. + When this function is called after the program has been linked, + the program will need to be relinked for the change to take effect. + \sa attributeLocation() */ void QGLShaderProgram::bindAttributeLocation(const char *name, int location) { Q_D(QGLShaderProgram); - if (!d->linked) { - glBindAttribLocation(d->programGuard.id(), location, name); - } else { - qWarning() << "QGLShaderProgram::bindAttributeLocation(" << name - << "): cannot bind after shader program is linked"; - } + if (!init()) + return; + glBindAttribLocation(d->programGuard.id(), location, name); + d->linked = false; // Program needs to be relinked. } /*! @@ -1020,6 +1021,9 @@ void QGLShaderProgram::bindAttributeLocation(const char *name, int location) Any attributes that have not been explicitly bound when the program is linked will be assigned locations automatically. + When this function is called after the program has been linked, + the program will need to be relinked for the change to take effect. + \sa attributeLocation() */ void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location) @@ -1035,6 +1039,9 @@ void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int locatio Any attributes that have not been explicitly bound when the program is linked will be assigned locations automatically. + When this function is called after the program has been linked, + the program will need to be relinked for the change to take effect. + \sa attributeLocation() */ void QGLShaderProgram::bindAttributeLocation(const QString& name, int location) @@ -1290,7 +1297,8 @@ void QGLShaderProgram::setAttributeValue(int location, const QColor& value) Q_D(QGLShaderProgram); Q_UNUSED(d); if (location != -1) { - GLfloat values[4] = {value.redF(), value.greenF(), value.blueF(), value.alphaF()}; + GLfloat values[4] = {GLfloat(value.redF()), GLfloat(value.greenF()), + GLfloat(value.blueF()), GLfloat(value.alphaF())}; glVertexAttrib4fv(location, values); } } @@ -2025,7 +2033,8 @@ void QGLShaderProgram::setUniformValue(int location, const QColor& color) Q_D(QGLShaderProgram); Q_UNUSED(d); if (location != -1) { - GLfloat values[4] = {color.redF(), color.greenF(), color.blueF(), color.alphaF()}; + GLfloat values[4] = {GLfloat(color.redF()), GLfloat(color.greenF()), + GLfloat(color.blueF()), GLfloat(color.alphaF())}; glUniform4fv(location, 1, values); } } @@ -2054,7 +2063,7 @@ void QGLShaderProgram::setUniformValue(int location, const QPoint& point) Q_D(QGLShaderProgram); Q_UNUSED(d); if (location != -1) { - GLfloat values[4] = {point.x(), point.y()}; + GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())}; glUniform2fv(location, 1, values); } } @@ -2083,7 +2092,7 @@ void QGLShaderProgram::setUniformValue(int location, const QPointF& point) Q_D(QGLShaderProgram); Q_UNUSED(d); if (location != -1) { - GLfloat values[4] = {point.x(), point.y()}; + GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())}; glUniform2fv(location, 1, values); } } @@ -2112,7 +2121,7 @@ void QGLShaderProgram::setUniformValue(int location, const QSize& size) Q_D(QGLShaderProgram); Q_UNUSED(d); if (location != -1) { - GLfloat values[4] = {size.width(), size.width()}; + GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.width())}; glUniform2fv(location, 1, values); } } @@ -2141,7 +2150,7 @@ void QGLShaderProgram::setUniformValue(int location, const QSizeF& size) Q_D(QGLShaderProgram); Q_UNUSED(d); if (location != -1) { - GLfloat values[4] = {size.width(), size.height()}; + GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())}; glUniform2fv(location, 1, values); } } @@ -2562,9 +2571,9 @@ void QGLShaderProgram::setUniformValue(int location, const QTransform& value) Q_UNUSED(d); if (location != -1) { GLfloat mat[3][3] = { - {value.m11(), value.m12(), value.m13()}, - {value.m21(), value.m22(), value.m23()}, - {value.m31(), value.m32(), value.m33()} + {GLfloat(value.m11()), GLfloat(value.m12()), GLfloat(value.m13())}, + {GLfloat(value.m21()), GLfloat(value.m22()), GLfloat(value.m23())}, + {GLfloat(value.m31()), GLfloat(value.m32()), GLfloat(value.m33())} }; glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]); } diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index c8307a0..306fd8b 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -3342,15 +3342,15 @@ void QGLEllipseMaskGenerator::drawMask(const QRect &rect) QTransform gl_to_qt(1, 0, 0, -1, 0, offscreen->drawableSize().height()); QTransform inv_matrix = gl_to_qt * matrix().inverted() * translate; - float m[3][4] = { { inv_matrix.m11(), inv_matrix.m12(), inv_matrix.m13() }, - { inv_matrix.m21(), inv_matrix.m22(), inv_matrix.m23() }, - { inv_matrix.m31(), inv_matrix.m32(), inv_matrix.m33() } }; + float m[3][4] = { { float(inv_matrix.m11()), float(inv_matrix.m12()), float(inv_matrix.m13()) }, + { float(inv_matrix.m21()), float(inv_matrix.m22()), float(inv_matrix.m23()) }, + { float(inv_matrix.m31()), float(inv_matrix.m32()), float(inv_matrix.m33()) } }; QPoint offs(screen_rect.left() - rect.left(), (offscreen->drawableSize().height() - screen_rect.top()) - (offscreen->offscreenSize().height() - rect.top())); // last component needs to be 1.0f to avoid Nvidia bug on linux - float ellipse_offset[4] = { offs.x(), offs.y(), 0.0f, 1.0f }; + float ellipse_offset[4] = { float(offs.x()), float(offs.y()), 0.0f, 1.0f }; GLfloat vertexArray[4 * 2]; qt_add_rect_to_array(rect, vertexArray); |