diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2009-04-17 08:04:08 (GMT) |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2009-04-17 08:16:35 (GMT) |
commit | b3f0d6e31c6897b1701de28d51980a81fb3e778f (patch) | |
tree | 29b8095070bb4f1585bee5a3eed45776c033ce5e /src/opengl/gl2paintengineex | |
parent | 537c26b2125994b42a5d00540ca4644582111573 (diff) | |
download | Qt-b3f0d6e31c6897b1701de28d51980a81fb3e778f.zip Qt-b3f0d6e31c6897b1701de28d51980a81fb3e778f.tar.gz Qt-b3f0d6e31c6897b1701de28d51980a81fb3e778f.tar.bz2 |
Correctly handle using GL pixmaps that still have an active engine.
In the case where a GL pixmap is used when there it still has an active
engine we need to ensure that the pixmap has been flushed from the
render FBO first. The newly added QGLPixmapData::copyBackFromRenderFbo()
handles this.
In addition, because several GL 2 paint engines can be active on the same
context at the same time, we can't make any assumptions and need to call
the newly added QGL2PaintEngineEx::ensureCreated() in the beginning of
any state-dependent paint engine function.
QGL2PaintEngineEx::ensureCreated() correctly transfers control to the
current engine if a different engine is active.
Running lance with -pixmap and -graphicssystem opengl works correctly
with the GL pixmap backend now.
Diffstat (limited to 'src/opengl/gl2paintengineex')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 47 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 3 |
2 files changed, 47 insertions, 3 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index fe70020..8bf3182 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -805,6 +805,7 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QGL2PaintEngineEx); + ensureActive(); d->setBrush(&brush); d->fill(path); d->setBrush(&(state()->brush)); // reset back to the state's brush @@ -814,6 +815,7 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) { Q_D(QGL2PaintEngineEx); + ensureActive(); if (pen.style() == Qt::NoPen) return; @@ -832,7 +834,6 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) d->setBrush(&(state()->brush)); } else return QPaintEngineEx::stroke(path, pen); - } void QGL2PaintEngineEx::penChanged() @@ -887,6 +888,7 @@ void QGL2PaintEngineEx::transformChanged() void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src) { Q_D(QGL2PaintEngineEx); + ensureActive(); d->transferMode(ImageDrawingMode); QGLContext *ctx = d->ctx; @@ -905,6 +907,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const Qt::ImageConversionFlags) { Q_D(QGL2PaintEngineEx); + ensureActive(); d->transferMode(ImageDrawingMode); QGLContext *ctx = d->ctx; @@ -921,6 +924,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem) { Q_D(QGL2PaintEngineEx); + ensureActive(); QOpenGLPaintEngineState *s = state(); const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); @@ -974,6 +978,9 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte const QImage &image = cache->image(); int margin = cache->glyphMargin(); + if (image.isNull()) + return; + ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); @@ -1085,6 +1092,16 @@ bool QGL2PaintEngineEx::end() { Q_D(QGL2PaintEngineEx); QGLContext *ctx = d->ctx; + if (ctx->d_ptr->active_engine != this) { + QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(d->last_engine); + if (engine) { + QGL2PaintEngineExPrivate *p = static_cast<QGL2PaintEngineExPrivate *>(engine->d_ptr); + p->transferMode(DefaultMode); + p->drawable.doneCurrent(); + } + d->drawable.makeCurrent(); + } + glUseProgram(0); d->transferMode(DefaultMode); d->drawable.swapBuffers(); @@ -1106,6 +1123,31 @@ bool QGL2PaintEngineEx::end() return false; } +void QGL2PaintEngineEx::ensureActive() +{ + Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; + + if (isActive() && ctx->d_ptr->active_engine != this) { + QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine); + if (engine) { + QGL2PaintEngineExPrivate *p = static_cast<QGL2PaintEngineExPrivate *>(engine->d_ptr); + p->transferMode(DefaultMode); + p->drawable.doneCurrent(); + } + d->drawable.makeCurrent(); + + ctx->d_ptr->active_engine = this; + + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + + glViewport(0, 0, d->width, d->height); + setState(state()); + d->updateDepthClip(); + } +} + /////////////////////////////////// State/Clipping stolen from QOpenGLPaintEngine ////////////////////////////////////////// @@ -1246,6 +1288,7 @@ void QGL2PaintEngineExPrivate::updateDepthClip() Q_Q(QGL2PaintEngineEx); + q->ensureActive(); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); @@ -1305,7 +1348,7 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) QOpenGLPaintEngineState *old_state = state(); const bool needsDepthClipUpdate = !old_state || s->clipEnabled != old_state->clipEnabled - || s->clipEnabled && s->clipRegion != old_state->clipRegion; + || (s->clipEnabled && s->clipRegion != old_state->clipRegion); QPaintEngineEx::setState(s); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 10e5337..b31f685 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -80,6 +80,8 @@ public: bool begin(QPaintDevice *device); bool end(); + void ensureActive(); + virtual void fill(const QVectorPath &path, const QBrush &brush); virtual void stroke(const QVectorPath &path, const QPen &pen); virtual void clip(const QVectorPath &path, Qt::ClipOperation op); @@ -102,7 +104,6 @@ public: Type type() const { return OpenGL; } - // State stuff is just for clipping and ripped off from QGLPaintEngine void setState(QPainterState *s); QPainterState *createState(QPainterState *orig) const; |