aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/items.pri2
-rw-r--r--src/quick/items/qquickrendercontrol.cpp224
-rw-r--r--src/quick/items/qquickrendercontrol_p.h94
-rw-r--r--src/quick/items/qquickwindow.cpp78
-rw-r--r--src/quick/items/qquickwindow.h4
-rw-r--r--src/quick/items/qquickwindow_p.h5
6 files changed, 392 insertions, 15 deletions
diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri
index 41cdb3526b..cb378b424b 100644
--- a/src/quick/items/items.pri
+++ b/src/quick/items/items.pri
@@ -10,6 +10,7 @@ HEADERS += \
$$PWD/qquickrectangle_p_p.h \
$$PWD/qquickwindow.h \
$$PWD/qquickwindow_p.h \
+ $$PWD/qquickrendercontrol_p.h \
$$PWD/qquickfocusscope_p.h \
$$PWD/qquickitemsmodule_p.h \
$$PWD/qquickpainteditem.h \
@@ -82,6 +83,7 @@ SOURCES += \
$$PWD/qquickitem.cpp \
$$PWD/qquickrectangle.cpp \
$$PWD/qquickwindow.cpp \
+ $$PWD/qquickrendercontrol.cpp \
$$PWD/qquickfocusscope.cpp \
$$PWD/qquickitemsmodule.cpp \
$$PWD/qquickpainteditem.cpp \
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
new file mode 100644
index 0000000000..7e4335ba63
--- /dev/null
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickrendercontrol_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTime>
+#include <QtCore/private/qabstractanimation_p.h>
+
+#include <QtGui/QOpenGLContext>
+#include <QtGui/private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+
+#include <QtQml/private/qqmlglobal_p.h>
+
+#include <QtQuick/QQuickWindow>
+#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qsgcontext_p.h>
+#include <private/qqmlprofilerservice_p.h>
+#include <QtCore/private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
+
+class QQuickRenderControlPrivate : public QObjectPrivate
+{
+public:
+ QQuickRenderControlPrivate()
+ : window(0)
+ {
+ sg = QSGContext::createDefaultContext();
+ rc = new QSGRenderContext(sg);
+ }
+
+ ~QQuickRenderControlPrivate()
+ {
+ delete rc;
+ delete sg;
+ }
+
+ QQuickWindow *window;
+ QSGContext *sg;
+ QSGRenderContext *rc;
+};
+
+/*!
+ \class QQuickRenderControl
+ \brief The QQuickRenderControl class provides a mechanism for rendering the Qt Quick scenegraph.
+
+ \internal
+
+ \inmodule QtQuick
+*/
+
+QQuickRenderControl::QQuickRenderControl()
+ : QObject(*(new QQuickRenderControlPrivate), 0)
+{
+}
+
+QQuickRenderControl::~QQuickRenderControl()
+{
+}
+
+void QQuickRenderControl::windowDestroyed()
+{
+ Q_D(QQuickRenderControl);
+ if (d->window == 0) {
+ d->rc->invalidate();
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ }
+}
+
+void QQuickRenderControl::initialize(QOpenGLContext *gl)
+{
+ Q_D(QQuickRenderControl);
+ if (!d->window)
+ return;
+ bool current = gl->makeCurrent(d->window);
+ if (current)
+ QQuickWindowPrivate::get(d->window)->context->initialize(gl);
+}
+
+void QQuickRenderControl::invalidate()
+{
+ Q_D(QQuickRenderControl);
+ QQuickWindowPrivate::get(d->window)->context->invalidate();
+}
+
+/*!
+ This function should be called as late as possible before
+ sync(). In a threaded scenario, rendering can happen in parallel with this function.
+ */
+void QQuickRenderControl::polishItems()
+{
+ Q_D(QQuickRenderControl);
+ if (!d->window || !QQuickWindowPrivate::get(d->window)->isRenderable())
+ return;
+
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ cd->polishItems();
+}
+
+/*!
+ Synchronize GUI and scenegraph. Returns true if the scene graph was changed.
+
+ This function is a synchronization point. Rendering can not happen in parallel.
+ */
+bool QQuickRenderControl::sync()
+{
+ Q_D(QQuickRenderControl);
+ if (!d->window || !QQuickWindowPrivate::get(d->window)->isRenderable())
+ return false;
+
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ cd->syncSceneGraph();
+
+ // TODO: find out if the sync actually caused a scenegraph update.
+ return true;
+}
+
+/*!
+ Render the scenegraph using the current context.
+ */
+void QQuickRenderControl::render()
+{
+ Q_D(QQuickRenderControl);
+ if (!d->window || !QQuickWindowPrivate::get(d->window)->isRenderable())
+ return;
+
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ cd->renderSceneGraph(d->window->size());
+}
+
+
+/*!
+ \fn void QQuickRenderControl::renderRequested()
+
+ This signal is emitted when the scene graph needs to be rendered. It is not necessary to call sync().
+*/
+
+/*!
+ \fn void QQuickRenderControl::sceneChanged()
+
+ This signal is emitted when the scene graph is updated, meaning that
+ polishItems() and sync() needs to be called. If sync() returns
+ true, then render() needs to be called.
+*/
+
+
+QImage QQuickRenderControl::grab()
+{
+ Q_D(QQuickRenderControl);
+ if (!d->window)
+ return QImage();
+
+ render();
+ QImage grabContent = qt_gl_read_framebuffer(d->window->size(), false, false);
+ return grabContent;
+}
+
+QSGContext *QQuickRenderControl::sceneGraphContext() const
+{
+ Q_D(const QQuickRenderControl);
+ return d->sg;
+}
+
+QSGRenderContext *QQuickRenderControl::renderContext(QSGContext *) const
+{
+ Q_D(const QQuickRenderControl);
+ return d->rc;
+}
+
+void QQuickRenderControl::setWindow(QQuickWindow *window)
+{
+ Q_D(QQuickRenderControl);
+ d->window = window;
+}
+
+QQuickWindow *QQuickRenderControl::window() const
+{
+ Q_D(const QQuickRenderControl);
+ return d->window;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/items/qquickrendercontrol_p.h b/src/quick/items/qquickrendercontrol_p.h
new file mode 100644
index 0000000000..7255a9ae0b
--- /dev/null
+++ b/src/quick/items/qquickrendercontrol_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKRENDERCONTROL_P_H
+#define QQUICKRENDERCONTROL_P_H
+
+#include <QtGui/QImage>
+#include <private/qtquickglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWindow;
+class QSGContext;
+class QSGRenderContext;
+class QAnimationDriver;
+class QOpenGLContext;
+class QQuickRenderControlPrivate;
+
+class Q_QUICK_PRIVATE_EXPORT QQuickRenderControl : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QQuickRenderControl)
+public:
+ QQuickRenderControl();
+ ~QQuickRenderControl();
+
+ QQuickWindow *window() const;
+
+ void windowDestroyed();
+
+ void initialize(QOpenGLContext *gl);
+ void invalidate();
+ void polishItems();
+ void render();
+ bool sync();
+
+ QImage grab();
+
+Q_SIGNALS:
+ void renderRequested();
+ void sceneChanged();
+
+private:
+ friend class QQuickWindowPrivate;
+ friend class QQuickWindow;
+ void setWindow(QQuickWindow *window);
+ inline void update() { /*emit*/ renderRequested(); }
+ inline void maybeUpdate() { /*emit*/ sceneChanged(); }
+
+ QSGContext *sceneGraphContext() const;
+ QSGRenderContext *renderContext(QSGContext *) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKRENDERCONTROL_P_H
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 2e74c59c20..f035e87d99 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -51,6 +51,7 @@
#include <QtQuick/private/qsgrenderer_p.h>
#include <QtQuick/private/qsgtexture_p.h>
#include <private/qsgrenderloop_p.h>
+#include <private/qquickrendercontrol_p.h>
#include <private/qquickanimatorcontroller_p.h>
#include <private/qguiapplication_p.h>
@@ -210,25 +211,32 @@ QQuickRootItem::QQuickRootItem()
void QQuickWindow::exposeEvent(QExposeEvent *)
{
Q_D(QQuickWindow);
- d->windowManager->exposureChanged(this);
+ if (d->windowManager)
+ d->windowManager->exposureChanged(this);
}
/*! \reimp */
void QQuickWindow::resizeEvent(QResizeEvent *)
{
- d_func()->windowManager->resize(this);
+ Q_D(QQuickWindow);
+ if (d->windowManager)
+ d->windowManager->resize(this);
}
/*! \reimp */
void QQuickWindow::showEvent(QShowEvent *)
{
- d_func()->windowManager->show(this);
+ Q_D(QQuickWindow);
+ if (d->windowManager)
+ d->windowManager->show(this);
}
/*! \reimp */
void QQuickWindow::hideEvent(QHideEvent *)
{
- d_func()->windowManager->hide(this);
+ Q_D(QQuickWindow);
+ if (d->windowManager)
+ d->windowManager->hide(this);
}
/*! \reimp */
@@ -284,7 +292,10 @@ void QQuickWindowPrivate::polishItems()
void QQuickWindow::update()
{
Q_D(QQuickWindow);
- d->windowManager->update(this);
+ if (d->windowManager)
+ d->windowManager->update(this);
+ else
+ d->renderControl->update();
}
void forcePolishHelper(QQuickItem *item)
@@ -391,12 +402,14 @@ QQuickWindowPrivate::QQuickWindowPrivate()
, context(0)
, renderer(0)
, windowManager(0)
+ , renderControl(0)
, clearColor(Qt::white)
, clearBeforeRendering(true)
, persistentGLContext(true)
, persistentSceneGraph(true)
, lastWheelEventAccepted(false)
, componentCompleted(true)
+ , forceRendering(false)
, renderTarget(0)
, renderTargetId(0)
, incubationController(0)
@@ -410,7 +423,7 @@ QQuickWindowPrivate::~QQuickWindowPrivate()
{
}
-void QQuickWindowPrivate::init(QQuickWindow *c)
+void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
{
q_ptr = c;
@@ -424,9 +437,24 @@ void QQuickWindowPrivate::init(QQuickWindow *c)
contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
customRenderMode = qgetenv("QSG_VISUALIZE");
- windowManager = QSGRenderLoop::instance();
- QSGContext *sg = windowManager->sceneGraphContext();
- context = windowManager->createRenderContext(sg);
+ renderControl = control;
+ if (renderControl)
+ renderControl->setWindow(q);
+
+ if (!renderControl)
+ windowManager = QSGRenderLoop::instance();
+
+ Q_ASSERT(windowManager || renderControl);
+
+ QSGContext *sg;
+ if (renderControl) {
+ sg = renderControl->sceneGraphContext();
+ context = renderControl->renderContext(sg);
+ } else {
+ sg = windowManager->sceneGraphContext();
+ context = windowManager->createRenderContext(sg);
+ }
+
q->setSurfaceType(QWindow::OpenGLSurface);
q->setFormat(sg->defaultSurfaceFormat());
@@ -1040,6 +1068,18 @@ QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent)
}
/*!
+ \internal
+*/
+QQuickWindow::QQuickWindow(QQuickRenderControl *control)
+ : QWindow(*(new QQuickWindowPrivate), 0)
+{
+ Q_D(QQuickWindow);
+ d->init(this, control);
+}
+
+
+
+/*!
Destroys the window.
*/
QQuickWindow::~QQuickWindow()
@@ -1047,7 +1087,10 @@ QQuickWindow::~QQuickWindow()
Q_D(QQuickWindow);
d->animationController->deleteLater();
- d->windowManager->windowDestroyed(this);
+ if (d->renderControl)
+ d->renderControl->windowDestroyed();
+ else
+ d->windowManager->windowDestroyed(this);
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
delete d->incubationController; d->incubationController = 0;
@@ -1075,7 +1118,8 @@ QQuickWindow::~QQuickWindow()
void QQuickWindow::releaseResources()
{
Q_D(QQuickWindow);
- d->windowManager->releaseResources(this);
+ if (d->windowManager)
+ d->windowManager->releaseResources(this);
QQuickPixmap::purgeCache();
}
@@ -2267,7 +2311,7 @@ void QQuickWindowPrivate::data_clear(QQmlListProperty<QObject> *property)
bool QQuickWindowPrivate::isRenderable() const
{
Q_Q(const QQuickWindow);
- return q->isExposed() && q->isVisible() && q->geometry().isValid();
+ return (forceRendering || (q->isExposed() && q->isVisible())) && q->geometry().isValid();
}
/*!
@@ -2638,7 +2682,10 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
void QQuickWindow::maybeUpdate()
{
Q_D(QQuickWindow);
- d->windowManager->maybeUpdate(this);
+ if (d->renderControl)
+ d->renderControl->maybeUpdate();
+ else
+ d->windowManager->maybeUpdate(this);
}
void QQuickWindow::cleanupSceneGraph()
@@ -2897,7 +2944,7 @@ QImage QQuickWindow::grabWindow()
return image;
}
- return d->windowManager->grab(this);
+ return d->renderControl ? d->renderControl->grab() : d->windowManager->grab(this);
}
/*!
@@ -2912,6 +2959,9 @@ QQmlIncubationController *QQuickWindow::incubationController() const
{
Q_D(const QQuickWindow);
+ if (!d->windowManager)
+ return 0; // TODO: make sure that this is safe
+
if (!d->incubationController)
d->incubationController = new QQuickWindowIncubationController(d->windowManager);
return d->incubationController;
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 5063b3b5db..233340d6fa 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -58,6 +58,7 @@ class QOpenGLFramebufferObject;
class QQmlIncubationController;
class QInputMethodEvent;
class QQuickCloseEvent;
+class QQuickRenderControl;
class Q_QUICK_EXPORT QQuickWindow : public QWindow
{
@@ -177,7 +178,10 @@ private Q_SLOTS:
private:
friend class QQuickItem;
+ friend class QQuickWidget;
+ friend class QQuickWidgetPrivate;
friend class QQuickAnimatorController;
+ explicit QQuickWindow(QQuickRenderControl*);
Q_DISABLE_COPY(QQuickWindow)
};
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 944a320dce..5f61403a40 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -74,6 +74,7 @@ QT_BEGIN_NAMESPACE
class QQuickAnimatorController;
class QSGRenderLoop;
+class QQuickRenderControl;
class QQuickDragGrabber;
class QQuickRootItem : public QQuickItem
@@ -103,7 +104,7 @@ public:
QQuickWindowPrivate();
virtual ~QQuickWindowPrivate();
- void init(QQuickWindow *);
+ void init(QQuickWindow *, QQuickRenderControl *control = 0);
void initContentItem();//Currently only used if items added in QML
QQuickRootItem *contentItem;
@@ -204,6 +205,7 @@ public:
QByteArray customRenderMode; // Default renderer supports "clip", "overdraw", "changes", "batches" and blank.
QSGRenderLoop *windowManager;
+ QQuickRenderControl *renderControl;
QQuickAnimatorController *animationController;
QColor clearColor;
@@ -217,6 +219,7 @@ public:
uint lastWheelEventAccepted : 1;
bool componentCompleted : 1;
+ bool forceRendering : 1;
QOpenGLFramebufferObject *renderTarget;
uint renderTargetId;