diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2010-09-09 15:12:57 (GMT) |
---|---|---|
committer | Samuel Rødal <samuel.rodal@nokia.com> | 2010-09-09 15:47:48 (GMT) |
commit | 6b7f0bb52f10a03758b5625bd7112d214627812a (patch) | |
tree | 175cff978ddf2e09e5c7f1110e00100865a3b68c /src/opengl | |
parent | 0d76ad42f5479fb21ad9cd64f7251a421cc6a151 (diff) | |
download | Qt-6b7f0bb52f10a03758b5625bd7112d214627812a.zip Qt-6b7f0bb52f10a03758b5625bd7112d214627812a.tar.gz Qt-6b7f0bb52f10a03758b5625bd7112d214627812a.tar.bz2 |
Some optimizations to the GL pixmap data.
- Don't use toImage() / fromImage() to copy when a render FBO is active.
- Use raster for rendering to small (< 32x32) pixmaps.
Reviewed-by: Trond
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/qpixmapdata_gl.cpp | 40 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl_p.h | 2 |
4 files changed, 44 insertions, 6 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 18192e3..aa217f6 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/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; |