Support setting an FBO as the render target for a canvas
authorGunnar Sletta <gunnar.sletta@nokia.com>
Fri, 1 Jul 2011 06:19:52 +0000 (08:19 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 1 Jul 2011 06:21:15 +0000 (08:21 +0200)
Change-Id: I8049580f1d2b27d6ebc4d595712939338c01b711
Reviewed-on: http://codereview.qt.nokia.com/986
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
src/declarative/items/qsgcanvas.cpp
src/declarative/items/qsgcanvas.h
src/declarative/items/qsgcanvas_p.h
src/declarative/scenegraph/qsgcontext.cpp
src/declarative/scenegraph/qsgcontext_p.h

index 3abbec3..343a7e1 100644 (file)
@@ -393,10 +393,10 @@ void QSGCanvasPrivate::syncSceneGraph()
 void QSGCanvasPrivate::renderSceneGraph(const QSize &size)
 {
     context->renderer()->setDeviceRect(QRect(QPoint(0, 0), size));
-    context->renderer()->setViewportRect(QRect(QPoint(0, 0), size));
+    context->renderer()->setViewportRect(QRect(QPoint(0, 0), renderTarget ? renderTarget->size() : size));
     context->renderer()->setProjectionMatrixToDeviceRect();
 
-    context->renderNextFrame();
+    context->renderNextFrame(renderTarget);
 
 #ifdef FRAME_TIMING
     sceneGraphRenderTime = frameTimer.elapsed();
@@ -432,6 +432,7 @@ QSGCanvasPrivate::QSGCanvasPrivate()
     , vsyncAnimations(false)
     , thread(0)
     , animationDriver(0)
+    , renderTarget(0)
 {
     threadedRendering = !qmlNoThreadedRenderer();
 }
@@ -1979,6 +1980,44 @@ QSGEngine *QSGCanvas::sceneGraphEngine() const
 }
 
 
+
+/*!
+    Sets the render target for this canvas to be \a fbo.
+
+    The specified fbo must be created in the context of the canvas
+    or one that shares with it.
+
+    \warning
+    This function can only be called from the thread doing
+    the rendering.
+ */
+
+void QSGCanvas::setRenderTarget(QGLFramebufferObject *fbo)
+{
+    Q_D(QSGCanvas);
+    if (d->context && d->context && QThread::currentThread() != d->context->thread()) {
+        qWarning("QSGCanvas::setRenderThread: Cannot set render target from outside the rendering thread");
+        return;
+    }
+
+    d->renderTarget = fbo;
+}
+
+
+
+/*!
+    Returns the render target for this canvas.
+
+    The default is to render to the surface of the canvas, in which
+    case the render target is 0.
+ */
+QGLFramebufferObject *QSGCanvas::renderTarget() const
+{
+    Q_D(const QSGCanvas);
+    return d->renderTarget;
+}
+
+
 /*!
     Grabs the contents of the framebuffer and returns it as an image.
 
@@ -2081,6 +2120,7 @@ void QSGCanvasRenderThread::run()
 #endif
 
         renderer->swapBuffers();
+
 #ifdef THREAD_DEBUG
         printf("                RenderThread: swap complete...\n");
 #endif
index 8913e41..aa0cdc8 100644 (file)
@@ -55,6 +55,8 @@ QT_MODULE(Declarative)
 class QSGItem;
 class QSGEngine;
 class QSGCanvasPrivate;
+class QGLFramebufferObject;
+
 class Q_DECLARATIVE_EXPORT QSGCanvas : public QGLWidget
 {
 Q_OBJECT
@@ -80,6 +82,9 @@ public:
 
     QImage grabFrameBuffer();
 
+    void setRenderTarget(QGLFramebufferObject *fbo);
+    QGLFramebufferObject *renderTarget() const;
+
 Q_SIGNALS:
     void sceneGraphInitialized();
 
index 7f7182e..c4c82b6 100644 (file)
@@ -65,6 +65,7 @@
 #include <QtCore/qwaitcondition.h>
 #include <private/qwidget_p.h>
 #include <private/qgl_p.h>
+#include <QtOpenGL/qglframebufferobject.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -168,6 +169,8 @@ public:
 
     QAnimationDriver *animationDriver;
 
+    QGLFramebufferObject *renderTarget;
+
     QHash<int, QSGItem *> itemForTouchPointId;
 };
 
index 682b514..f5a082b 100644 (file)
@@ -246,14 +246,20 @@ bool QSGContext::isReady() const
 }
 
 
-void QSGContext::renderNextFrame()
+void QSGContext::renderNextFrame(QGLFramebufferObject *fbo)
 {
     Q_D(QSGContext);
 
     emit d->engine.beforeRendering();
 
     cleanupTextures();
-    d->renderer->renderScene();
+
+    if (fbo) {
+        BindableFbo bindable(fbo);
+        d->renderer->renderScene(bindable);
+    } else {
+        d->renderer->renderScene();
+    }
 
     emit d->engine.afterRendering();
 
index 1344ac7..5ce2e9e 100644 (file)
@@ -65,6 +65,7 @@ class QSGMaterialShader;
 class QSGEngine;
 
 class QGLContext;
+class QGLFramebufferObject;
 
 class Q_DECLARATIVE_EXPORT QSGContext : public QObject
 {
@@ -89,7 +90,7 @@ public:
 
     QSGMaterialShader *prepareMaterial(QSGMaterial *material);
 
-    virtual void renderNextFrame();
+    virtual void renderNextFrame(QGLFramebufferObject *fbo = 0);
 
     virtual QSGRectangleNode *createRectangleNode();
     virtual QSGImageNode *createImageNode();