summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-09-11 14:09:47 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-09-11 14:42:56 (GMT)
commit3fed939e82e4946546775602f4898c363871c3f2 (patch)
tree7ae06261c354289783747704fc5e4129837c31c2 /src/opengl
parent33d1c616d8d4085ba6fa848bafaec66576eba224 (diff)
downloadQt-3fed939e82e4946546775602f4898c363871c3f2.zip
Qt-3fed939e82e4946546775602f4898c363871c3f2.tar.gz
Qt-3fed939e82e4946546775602f4898c363871c3f2.tar.bz2
Made GL window surface work better with native child widgets.
Need to unbind the window surface FBO and re-bind it in the child widget's context before doing a blit. Reviewed-by: Kim
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/qglframebufferobject.cpp2
-rw-r--r--src/opengl/qwindowsurface_gl.cpp80
2 files changed, 64 insertions, 18 deletions
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index f15aa01..81f2aa9 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -854,6 +854,7 @@ bool QGLFramebufferObject::bind()
d->valid = d->checkFramebufferStatus();
const QGLContext *context = QGLContext::currentContext();
if (d->valid && context) {
+ Q_ASSERT(QGLContextPrivate::contextGroup(context) == ctx);
// Save the previous setting to automatically restore in release().
if (context->d_ptr->current_fbo != d->fbo) {
d->previous_fbo = context->d_ptr->current_fbo;
@@ -885,6 +886,7 @@ bool QGLFramebufferObject::release()
const QGLContext *context = QGLContext::currentContext();
if (context) {
+ Q_ASSERT(QGLContextPrivate::contextGroup(context) == ctx);
// Restore the previous setting for stacked framebuffer objects.
if (d->previous_fbo != context->d_ptr->current_fbo) {
context->d_ptr->current_fbo = d->previous_fbo;
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index c2f05cc..e89352d 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -71,6 +71,7 @@
#include <private/qgraphicssystem_gl_p.h>
#include <private/qpaintengineex_opengl2_p.h>
+#include <private/qpixmapdata_gl_p.h>
#ifndef QT_OPENGL_ES_2
#include <private/qpaintengine_opengl_p.h>
@@ -399,6 +400,11 @@ void QGLWindowSurface::endPaint(const QRegion &rgn)
void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
{
+ if (context() && widget != window()) {
+ qWarning("No native child widget support in GL window surface without FBOs or pixel buffers");
+ return;
+ }
+
QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget();
Q_ASSERT(parent);
@@ -473,7 +479,22 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
return;
}
+ QGLContext *previous_ctx = const_cast<QGLContext *>(QGLContext::currentContext());
QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext);
+
+ if (ctx != previous_ctx) {
+ if (d_ptr->fbo && d_ptr->fbo->isBound())
+ d_ptr->fbo->release();
+ ctx->makeCurrent();
+ }
+
+ QSize size = widget->rect().size();
+ if (d_ptr->destructive_swap_buffers && ctx->format().doubleBuffer()) {
+ rect = parent->rect();
+ br = rect.translated(wOffset + offset);
+ size = parent->size();
+ }
+
GLuint texture;
if (d_ptr->fbo) {
texture = d_ptr->fbo->texture();
@@ -486,31 +507,54 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
glBindTexture(target, 0);
}
- QSize size = widget->rect().size();
- if (d_ptr->destructive_swap_buffers && ctx->format().doubleBuffer()) {
- rect = parent->rect();
- br = rect.translated(wOffset);
- size = parent->size();
- }
-
glDisable(GL_SCISSOR_TEST);
- if (d_ptr->fbo && QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) {
+ if (d_ptr->fbo && (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit)) {
const int h = d_ptr->fbo->height();
- const int x0 = rect.left();
- const int x1 = rect.left() + rect.width();
- const int y0 = h - (rect.top() + rect.height());
- const int y1 = h - rect.top();
+ const int sx0 = br.left();
+ const int sx1 = br.left() + br.width();
+ const int sy0 = h - (br.top() + br.height());
+ const int sy1 = h - br.top();
+
+ const int tx0 = rect.left();
+ const int tx1 = rect.left() + rect.width();
+ const int ty0 = parent->height() - (rect.top() + rect.height());
+ 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);
+ glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
+ tx0, ty0, tx1, ty1,
+ GL_COLOR_BUFFER_BIT,
+ GL_NEAREST);
- glBlitFramebufferEXT(x0, y0, x1, y1,
- x0, y0, x1, y1,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, d_ptr->fbo->handle());
+ } else {
+ // can't do sub-region blits with multisample FBOs
+ QGLFramebufferObject *temp = qgl_fbo_pool()->acquire(d_ptr->fbo->size(), QGLFramebufferObjectFormat());
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, temp->handle());
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle());
+
+ glBlitFramebufferEXT(0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(),
+ 0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(),
+ GL_COLOR_BUFFER_BIT,
+ GL_NEAREST);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, temp->handle());
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, d_ptr->fbo->handle());
+ glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
+ tx0, ty0, tx1, ty1,
+ GL_COLOR_BUFFER_BIT,
+ GL_NEAREST);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
+
+ qgl_fbo_pool()->release(temp);
+ }
}
#if !defined(QT_OPENGL_ES_2)
else {