diff options
author | Peter Yard <peter.yard@nokia.com> | 2010-12-22 06:04:57 (GMT) |
---|---|---|
committer | Peter Yard <peter.yard@nokia.com> | 2010-12-22 06:04:57 (GMT) |
commit | 53b018a42813e44787aa1edc35d59feaa86cf9d7 (patch) | |
tree | 7cce8f18faf26a87cfb5f27d1417c2a2ec86470c /src/opengl | |
parent | 55c32b91a298d52bd7c29968d21b4b7a5ee741e4 (diff) | |
parent | afa22a20c1b89960b647b0e3a9dc390fe6f87eae (diff) | |
download | Qt-53b018a42813e44787aa1edc35d59feaa86cf9d7.zip Qt-53b018a42813e44787aa1edc35d59feaa86cf9d7.tar.gz Qt-53b018a42813e44787aa1edc35d59feaa86cf9d7.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 52 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 2 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 16 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 1 | ||||
-rw-r--r-- | src/opengl/qgl_egl.cpp | 2 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 1 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_gl.cpp | 13 |
7 files changed, 77 insertions, 10 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 4a64f39..668a3f0 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -163,6 +163,8 @@ void QGL2PaintEngineExPrivate::setBrush(const QBrush& brush) Q_ASSERT(newStyle != Qt::NoBrush); currentBrush = brush; + if (!currentBrushPixmap.isNull()) + currentBrushPixmap = QPixmap(); brushUniformsDirty = true; // All brushes have at least one uniform if (newStyle > Qt::SolidPattern) @@ -221,10 +223,14 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform); } else if (style == Qt::TexturePattern) { - const QPixmap& texPixmap = currentBrush.texture(); + currentBrushPixmap = currentBrush.texture(); + + int max_texture_size = ctx->d_func()->maxTextureSize(); + if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size) + currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - QGLTexture *tex = ctx->d_func()->bindTexture(texPixmap, GL_TEXTURE_2D, GL_RGBA, + QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption | QGLContext::CanFlipNativePixmapBindOption); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); @@ -1305,13 +1311,30 @@ void QGL2PaintEngineEx::transformChanged() } +static const QRectF scaleRect(const QRectF &r, qreal sx, qreal sy) +{ + return QRectF(r.x() * sx, r.y() * sy, r.width() * sx, r.height() * sy); +} + void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src) { Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; + + int max_texture_size = ctx->d_func()->maxTextureSize(); + if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) { + QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); + + const qreal sx = scaled.width() / qreal(pixmap.width()); + const qreal sy = scaled.height() / qreal(pixmap.height()); + + drawPixmap(dest, scaled, scaleRect(src, sx, sy)); + return; + } + ensureActive(); d->transferMode(ImageDrawingMode); - QGLContext *ctx = d->ctx; glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, @@ -1334,11 +1357,24 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const Qt::ImageConversionFlags) { Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; + + int max_texture_size = ctx->d_func()->maxTextureSize(); + if (image.width() > max_texture_size || image.height() > max_texture_size) { + QImage scaled = image.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); + + const qreal sx = scaled.width() / qreal(image.width()); + const qreal sy = scaled.height() / qreal(image.height()); + + drawImage(dest, scaled, scaleRect(src, sx, sy)); + return; + } + ensureActive(); d->transferMode(ImageDrawingMode); - QGLContext *ctx = d->ctx; glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption); GLuint id = texture->id; @@ -1737,7 +1773,13 @@ void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *frag } ensureActive(); - d->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); + int max_texture_size = d->ctx->d_func()->maxTextureSize(); + if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) { + QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); + d->drawPixmapFragments(fragments, fragmentCount, scaled, hints); + } else { + d->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); + } } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index b255e75..02b737b 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -274,6 +274,8 @@ public: QBrush currentBrush; // May not be the state's brush! const QBrush noBrush; + QPixmap currentBrushPixmap; + QGL2PEXVertexArray vertexCoordinateArray; QGL2PEXVertexArray textureCoordinateArray; QVector<GLushort> elementIndices; diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 66445cd..ba311c3 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -83,13 +83,9 @@ void QGLTextureGlyphCache::clear() if (ctx) { QGLShareContextScope scope(ctx); - if (!ctx->d_ptr->workaround_brokenFBOReadBack) - glDeleteFramebuffers(1, &m_fbo); - if (m_width || m_height) glDeleteTextures(1, &m_texture); - m_fbo = 0; m_texture = 0; m_width = 0; m_height = 0; @@ -105,6 +101,13 @@ void QGLTextureGlyphCache::clear() QGLTextureGlyphCache::~QGLTextureGlyphCache() { + if (ctx) { + QGLShareContextScope scope(ctx); + + if (!ctx->d_ptr->workaround_brokenFBOReadBack) + glDeleteFramebuffers(1, &m_fbo); + } + clear(); } @@ -320,6 +323,9 @@ int QGLTextureGlyphCache::maxTextureWidth() const int QGLTextureGlyphCache::maxTextureHeight() const { - return ctx->d_ptr->maxTextureSize(); + if (ctx->d_ptr->workaround_brokenTexSubImage) + return qMin(1024, ctx->d_ptr->maxTextureSize()); + else + return ctx->d_ptr->maxTextureSize(); } QT_END_NAMESPACE diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 18f1203..9bf879a 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1706,6 +1706,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) active_engine = 0; workaround_needsFullClearOnEveryFrame = false; workaround_brokenFBOReadBack = false; + workaround_brokenTexSubImage = false; workaroundsCached = false; workaround_brokenTextureFromPixmap = false; diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 8902099..6f9e39c 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -204,6 +204,8 @@ void QGLContext::makeCurrent() const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION); if (egl_version && strstr(egl_version, "1.3")) d->workaround_brokenFBOReadBack = true; + else if (egl_version && strstr(egl_version, "1.4")) + d->workaround_brokenTexSubImage = true; } } } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index b46d428..bf830ba 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -401,6 +401,7 @@ public: // workarounds for driver/hw bugs on different platforms uint workaround_needsFullClearOnEveryFrame : 1; uint workaround_brokenFBOReadBack : 1; + uint workaround_brokenTexSubImage : 1; uint workaroundsCached : 1; uint workaround_brokenTextureFromPixmap : 1; diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index f64b93c..7dc7dc7 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -267,6 +267,7 @@ struct QGLWindowSurfacePrivate int tried_pb : 1; int destructive_swap_buffers : 1; int geometry_updated : 1; + int did_paint : 1; QGLContext *ctx; @@ -330,6 +331,7 @@ QGLWindowSurface::QGLWindowSurface(QWidget *window) d_ptr->glDevice.d = d_ptr; d_ptr->q_ptr = this; d_ptr->geometry_updated = false; + d_ptr->did_paint = false; } QGLWindowSurface::~QGLWindowSurface() @@ -461,6 +463,8 @@ void QGLWindowSurface::beginPaint(const QRegion &) glClearColor(0.0, 0.0, 0.0, 0.0); glClear(clearFlags); } + + d_ptr->did_paint = true; } void QGLWindowSurface::endPaint(const QRegion &rgn) @@ -513,6 +517,13 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & if (d_ptr->geometry_updated) return; + // did_paint is set to true in ::beginPaint. ::beginPaint means that we + // at least cleared the background (= painted something). In EGL API it's a + // mistakte to call swapBuffers if nothing was painted. This check protects + // the flush func from being executed if it's for nothing. + if (!d_ptr->did_paint) + return; + QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); Q_ASSERT(parent); @@ -736,6 +747,8 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & ctx->swapBuffers(); else glFlush(); + + d_ptr->did_paint = false; } |