summaryrefslogtreecommitdiffstats
path: root/src/opengl/gl2paintengineex
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-04-17 08:04:08 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-04-17 08:16:35 (GMT)
commitb3f0d6e31c6897b1701de28d51980a81fb3e778f (patch)
tree29b8095070bb4f1585bee5a3eed45776c033ce5e /src/opengl/gl2paintengineex
parent537c26b2125994b42a5d00540ca4644582111573 (diff)
downloadQt-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.cpp47
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h3
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;