diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-09-10 18:04:39 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-09-10 18:04:39 (GMT) |
commit | b3981fd1f7b82742857c613af6dfbe41b5493577 (patch) | |
tree | 957b84d8f1792f9e5a43c879274469c4f07168ea /src/opengl | |
parent | e0ef11578048620b3f107b7a357fed3aade0d21e (diff) | |
parent | 72cc21e597f2d77ea1be3c1a3f7df36d8909d2fc (diff) | |
download | Qt-b3981fd1f7b82742857c613af6dfbe41b5493577.zip Qt-b3981fd1f7b82742857c613af6dfbe41b5493577.tar.gz Qt-b3981fd1f7b82742857c613af6dfbe41b5493577.tar.bz2 |
Merge remote branch 'origin/4.7' into qt-master-from-4.7
Conflicts:
bin/syncqt
demos/declarative/snake/content/snake.js
demos/declarative/snake/snake.qml
doc/src/development/qmake-manual.qdoc
src/corelib/plugin/plugin.pri
src/gui/kernel/qapplication_win.cpp
src/gui/kernel/qdesktopwidget_win.cpp
src/gui/painting/qdrawhelper.cpp
tests/auto/qdir/tst_qdir.cpp
tools/qdoc3/test/assistant.qdocconf
tools/qdoc3/test/designer.qdocconf
tools/qdoc3/test/linguist.qdocconf
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 6 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 2 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 9 | ||||
-rw-r--r-- | src/opengl/qgl_mac.mm | 14 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl.cpp | 40 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl_p.h | 2 | ||||
-rw-r--r-- | src/opengl/qwindowsurface_gl.cpp | 20 |
7 files changed, 78 insertions, 15 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 6e56553..b762bcc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -591,6 +591,12 @@ void QGL2PaintEngineEx::endNativePainting() d->nativePaintingActive = false; } +void QGL2PaintEngineEx::invalidateState() +{ + Q_D(QGL2PaintEngineEx); + d->needsSync = true; +} + bool QGL2PaintEngineEx::isNativePaintingActive() const { Q_D(const QGL2PaintEngineEx); return d->nativePaintingActive; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 59b90d8..b255e75 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -151,6 +151,8 @@ public: void beginNativePainting(); void endNativePainting(); + void invalidateState(); + QPixmapFilter *pixmapFilter(int type, const QPixmapFilter *prototype); void setRenderTextActive(bool); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index e4967a6..deac025 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2118,11 +2118,8 @@ void QGLContextPrivate::syncGlState() #ifdef QT_NO_EGL void QGLContextPrivate::swapRegion(const QRegion *) { - static bool firstWarning = true; - if (firstWarning) { - qWarning() << "::swapRegion called but not supported!"; - firstWarning = false; - } + Q_Q(QGLContext); + q->swapBuffers(); } #endif @@ -5324,6 +5321,8 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions() glExtensions |= FragmentProgram; if (extensions.match("GL_ARB_fragment_shader")) glExtensions |= FragmentShader; + if (extensions.match("GL_ARB_shader_objects")) + glExtensions |= FragmentShader; if (extensions.match("GL_ARB_ES2_compatibility")) glExtensions |= ES2Compatibility; if (extensions.match("GL_ARB_texture_mirrored_repeat")) diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index 66fe7d3..f023a97 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -697,9 +697,17 @@ void QGLContext::updatePaintDevice() QWidget *w = (QWidget *)d->paintDevice; NSView *view = qt_mac_nativeview_for(w); - // ideally we would use QWidget::isVisible(), but we get "invalid drawable" errors - if (![(NSWindow *)qt_mac_window_for(w) isVisible]) - return; + // Trying to attach the GL context to the NSView will fail with + // "invalid drawable" if done too soon, but we have to make sure + // the connection is made before the first paint event. Using + // the NSView do to this check fails as the NSView is visible + // before it's safe to connect, and using the NSWindow fails as + // the NSWindow will become visible after the first paint event. + // This leaves us with the QWidget, who's visible state seems + // to match the point in time when it's safe to connect. + if (!w || !w->isVisible()) + return; // Not safe to attach GL context to view yet + if ([static_cast<NSOpenGLContext *>(d->cx) view] != view && ![view isHidden]) [static_cast<NSOpenGLContext *>(d->cx) setView:view]; } else if (d->paintDevice->devType() == QInternal::Pixmap) { diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 1efd398..89000bb 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -472,13 +472,42 @@ bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect) void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect) { - if (data->classId() != QPixmapData::OpenGLClass) { + if (data->classId() != QPixmapData::OpenGLClass || !static_cast<const QGLPixmapData *>(data)->useFramebufferObjects()) { QPixmapData::copy(data, rect); return; } - // can be optimized to do a framebuffer blit or similar ... - QPixmapData::copy(data, rect); + const QGLPixmapData *other = static_cast<const QGLPixmapData *>(data); + if (other->m_renderFbo) { + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + + resize(rect.width(), rect.height()); + m_hasAlpha = other->m_hasAlpha; + ensureCreated(); + + if (!ctx->d_ptr->fbo) + glGenFramebuffers(1, &ctx->d_ptr->fbo); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, m_texture.id, 0); + + if (!other->m_renderFbo->isBound()) + glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle()); + + glDisable(GL_SCISSOR_TEST); + if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2) + static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine)->invalidateState(); + + glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(), + 0, 0, w, h, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + + glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); + } else { + QPixmapData::copy(data, rect); + } } void QGLPixmapData::fill(const QColor &color) @@ -623,11 +652,12 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const } } -bool QGLPixmapData::useFramebufferObjects() +bool QGLPixmapData::useFramebufferObjects() const { return QGLFramebufferObject::hasOpenGLFramebufferObjects() && QGLFramebufferObject::hasOpenGLFramebufferBlit() - && qt_gl_preferGL2Engine(); + && qt_gl_preferGL2Engine() + && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps } QPaintEngine* QGLPixmapData::paintEngine() const diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 736a28e..4cb67b0 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -145,7 +145,7 @@ private: void copyBackFromRenderFbo(bool keepCurrentFboBound) const; QSize size() const { return QSize(w, h); } - static bool useFramebufferObjects(); + bool useFramebufferObjects() const; QImage fillImage(const QColor &color) const; diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index b86fb78..e84bc29 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -426,6 +426,20 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, void QGLWindowSurface::beginPaint(const QRegion &) { + if (! context()) + return; + + int clearFlags = 0; + + if (context()->d_func()->workaround_needsFullClearOnEveryFrame) + clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; + else if (context()->format().alpha()) + clearFlags = GL_COLOR_BUFFER_BIT; + + if (clearFlags) { + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(clearFlags); + } } void QGLWindowSurface::endPaint(const QRegion &rgn) @@ -560,7 +574,9 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & const int ty1 = parent->height() - rect.top(); if (window() == parent || d_ptr->fbo->format().samples() <= 1) { - // glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); + if (ctx->d_ptr->current_fbo != 0) + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); glBlitFramebufferEXT(sx0, sy0, sx1, sy1, @@ -593,6 +609,8 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & qgl_fbo_pool()->release(temp); } + + ctx->d_ptr->current_fbo = 0; } #if !defined(QT_OPENGL_ES_2) else { |