summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar@trolltech.com>2009-09-21 10:24:03 (GMT)
committerGunnar Sletta <gunnar@trolltech.com>2009-09-21 11:09:24 (GMT)
commit5dbd70c6bf294f85663f1c0f809afab73fea2500 (patch)
tree9e080ca4ddab3cc8901874b2d807c6a9d4594716 /src/opengl
parent0b9c7fab30bafa24ff55e7eb1bc868517d782486 (diff)
downloadQt-5dbd70c6bf294f85663f1c0f809afab73fea2500.zip
Qt-5dbd70c6bf294f85663f1c0f809afab73fea2500.tar.gz
Qt-5dbd70c6bf294f85663f1c0f809afab73fea2500.tar.bz2
Refactored gl window surface a bit.
The logic was a bit messy and didn't work on Mac OS X. On Linux we also had issues with 8xxx nvidia cards which didn't render properly. The FBO is now unbound between calls to beginPaint(), which prevents other gl calls from messing it up, which is probably what was the error in the first place. In addition, on Mac OS X, we also call the upatePaintDevice() as a result of setGeometry() to force-update the dimensions of the context. Reviewed-by: Trond
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/qwindowsurface_gl.cpp80
1 files changed, 43 insertions, 37 deletions
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index b2420ba..e34b637 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -241,6 +241,7 @@ struct QGLWindowSurfacePrivate
int tried_fbo : 1;
int tried_pb : 1;
int destructive_swap_buffers : 1;
+ int geometry_updated : 1;
QGLContext *ctx;
@@ -306,6 +307,7 @@ QGLWindowSurface::QGLWindowSurface(QWidget *window)
d_ptr->destructive_swap_buffers = qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull();
d_ptr->glDevice.d = d_ptr;
d_ptr->q_ptr = this;
+ d_ptr->geometry_updated = false;
}
QGLWindowSurface::~QGLWindowSurface()
@@ -349,9 +351,7 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
QGLContext *ctx = new QGLContext(surfaceFormat, widget);
ctx->create(qt_gl_share_widget()->context());
-#ifdef Q_WS_MAC
- ctx->updatePaintDevice();
-#endif
+
widgetPrivate->extraData()->glContext = ctx;
union { QGLContext **ctxPtr; void **voidPtr; };
@@ -378,8 +378,6 @@ QPaintDevice *QGLWindowSurface::paintDevice()
if (d_ptr->ctx)
return &d_ptr->glDevice;
- QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
- ctx->makeCurrent();
return d_ptr->fbo;
}
@@ -387,7 +385,6 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize,
void QGLWindowSurface::beginPaint(const QRegion &)
{
- updateGeometry();
}
void QGLWindowSurface::endPaint(const QRegion &rgn)
@@ -411,6 +408,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
if (!geometry().isValid())
return;
+ // Needed to support native child-widgets...
hijackWindow(parent);
QRect br = rgn.boundingRect().translated(offset);
@@ -480,9 +478,10 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
QGLContext *previous_ctx = const_cast<QGLContext *>(QGLContext::currentContext());
QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext);
+ // QPainter::end() should have unbound the fbo, otherwise something is very wrong...
+ Q_ASSERT(!d_ptr->fbo || !d_ptr->fbo->isBound());
+
if (ctx != previous_ctx) {
- if (d_ptr->fbo && d_ptr->fbo->isBound())
- d_ptr->fbo->release();
ctx->makeCurrent();
}
@@ -493,18 +492,6 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
size = parent->size();
}
- GLuint texture;
- if (d_ptr->fbo) {
- texture = d_ptr->fbo->texture();
- } else {
- d_ptr->pb->makeCurrent();
- glBindTexture(target, d_ptr->pb_tex_id);
- const uint bottom = window()->height() - (br.y() + br.height());
- glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
- texture = d_ptr->pb_tex_id;
- glBindTexture(target, 0);
- }
-
glDisable(GL_SCISSOR_TEST);
if (d_ptr->fbo && (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit)) {
@@ -521,14 +508,15 @@ 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);
+ // glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle());
glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
tx0, ty0, tx1, ty1,
GL_COLOR_BUFFER_BIT,
GL_NEAREST);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, d_ptr->fbo->handle());
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
} else {
// can't do sub-region blits with multisample FBOs
QGLFramebufferObject *temp = qgl_fbo_pool()->acquire(d_ptr->fbo->size(), QGLFramebufferObjectFormat());
@@ -556,15 +544,24 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
}
#if !defined(QT_OPENGL_ES_2)
else {
+ GLuint texture;
+ if (d_ptr->fbo) {
+ texture = d_ptr->fbo->texture();
+ } else {
+ d_ptr->pb->makeCurrent();
+ glBindTexture(target, d_ptr->pb_tex_id);
+ const uint bottom = window()->height() - (br.y() + br.height());
+ glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
+ texture = d_ptr->pb_tex_id;
+ glBindTexture(target, 0);
+ }
+
glDisable(GL_DEPTH_TEST);
if (d_ptr->fbo) {
d_ptr->fbo->release();
} else {
ctx->makeCurrent();
-#ifdef Q_WS_MAC
- ctx->updatePaintDevice();
-#endif
}
glMatrixMode(GL_MODELVIEW);
@@ -593,9 +590,27 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
glFlush();
}
-void QGLWindowSurface::updateGeometry()
+
+void QGLWindowSurface::setGeometry(const QRect &rect)
{
- QRect rect = QWindowSurface::geometry();
+ QWindowSurface::setGeometry(rect);
+ d_ptr->geometry_updated = true;
+}
+
+
+void QGLWindowSurface::updateGeometry() {
+ if (!d_ptr->geometry_updated)
+ return;
+ d_ptr->geometry_updated = false;
+
+
+ QRect rect = geometry();
+ hijackWindow(window());
+ QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
+
+#ifdef Q_WS_MAC
+ ctx->updatePaintDevice();
+#endif
const GLenum target = GL_TEXTURE_2D;
@@ -625,8 +640,6 @@ void QGLWindowSurface::updateGeometry()
&& qt_gl_preferGL2Engine())
{
d_ptr->tried_fbo = true;
- hijackWindow(window());
- QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
ctx->d_ptr->internal_context = true;
ctx->makeCurrent();
delete d_ptr->fbo;
@@ -640,7 +653,7 @@ void QGLWindowSurface::updateGeometry()
format.setSamples(8);
d_ptr->fbo = new QGLFramebufferObject(rect.size(), format);
- d_ptr->fbo->bind();
+
if (d_ptr->fbo->isValid()) {
qDebug() << "Created Window Surface FBO" << rect.size()
<< "with samples" << d_ptr->fbo->format().samples();
@@ -697,8 +710,6 @@ void QGLWindowSurface::updateGeometry()
}
#endif // !defined(QT_OPENGL_ES_2)
- hijackWindow(window());
- QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
ctx->makeCurrent();
if (d_ptr->destructive_swap_buffers) {
@@ -716,11 +727,6 @@ void QGLWindowSurface::updateGeometry()
d_ptr->ctx->d_ptr->internal_context = true;
}
-void QGLWindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
-}
-
bool QGLWindowSurface::scroll(const QRegion &area, int dx, int dy)
{
// this code randomly fails currently for unknown reasons