QT_BEGIN_NAMESPACE
+const QEvent::Type QEvent_Sync = QEvent::Type(QEvent::User);
+const QEvent::Type QEvent_DeferredUpdate = QEvent::Type(QEvent::User + 1);
+
#define QQUICK_CANVAS_TIMING
#ifdef QQUICK_CANVAS_TIMING
, isPaintCompleted(false)
, isPostingSyncEvent(false)
, isRenderBlocked(false)
+ , isExternalUpdatePending(false)
, syncAlreadyHappened(false)
, inSync(false)
, shouldExit(false)
, hasExited(false)
- , renderThreadAwakened(false)
+ , isDeferredUpdatePosted(false)
, canvasToGrab(0)
{
sg->moveToThread(this);
void paint(QQuickCanvas *canvas);
QImage grab(QQuickCanvas *canvas);
void resize(QQuickCanvas *canvas, const QSize &size);
+ void handleDeferredUpdate();
void maybeUpdate(QQuickCanvas *canvas);
void startRendering();
uint inSync : 1;
uint shouldExit : 1;
uint hasExited : 1;
- uint renderThreadAwakened : 1;
- uint isGuiAboutToBeBlockedForSync : 1;
+ uint isDeferredUpdatePosted : 1;
QQuickCanvas *canvasToGrab;
QImage grabContent;
QSize viewportSize;
uint sizeWasChanged : 1;
- uint isExternalUpdatePending : 1;
};
QHash<QQuickCanvas *, CanvasData *> m_rendered_windows;
#endif
CanvasData *data = new CanvasData;
- data->isExternalUpdatePending = true;
data->sizeWasChanged = false;
data->windowSize = canvas->size();
m_rendered_windows[canvas] = data;
+
+ isExternalUpdatePending = true;
}
printf(" RenderThread: *** NEW FRAME ***\n");
#endif
+ isExternalUpdatePending = false;
handleAddedWindows();
if (!isGuiLocked) {
printf(" RenderThread: aquired sync lock...\n");
#endif
allowMainThreadProcessingFlag = false;
- QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ QCoreApplication::postEvent(this, new QEvent(QEvent_Sync));
#ifdef THREAD_DEBUG
printf(" RenderThread: going to sleep...\n");
glViewport(0, 0, canvasData->viewportSize.width(), canvasData->viewportSize.height());
}
- canvasData->isExternalUpdatePending = false;
canvasPrivate->syncSceneGraph();
}
inSync = false;
isPaintCompleted = true;
- bool isExternalUpdatePending = false;
-
// Update sizes...
for (QHash<QQuickCanvas *, CanvasData *>::const_iterator it = m_rendered_windows.constBegin();
it != m_rendered_windows.constEnd(); ++it) {
canvasData->renderedSize = canvasData->viewportSize;
canvasData->sizeWasChanged = false;
}
- isExternalUpdatePending |= canvasData->isExternalUpdatePending;
}
{
Q_ASSERT(QThread::currentThread() == qApp->thread());
- if (e->type() == QEvent::User) {
+ if (e->type() == QEvent_Sync) {
// If all canvases have been hidden, ignore the event
if (!isRunning())
}
return true;
+ } else if (e->type() == QEvent_DeferredUpdate) {
+ handleDeferredUpdate();
} else if (e->type() == QEvent::Timer) {
#ifdef THREAD_DEBUG
if (!guiAlreadyLocked)
lockInGui();
- renderThreadAwakened = false;
-
for (QHash<QQuickCanvas *, CanvasData *>::const_iterator it = m_rendered_windows.constBegin();
it != m_rendered_windows.constEnd(); ++it) {
QQuickCanvasPrivate::get(it.key())->polishItems();
isGuiLocked = 0;
isPostingSyncEvent = false;
syncAlreadyHappened = false;
- renderThreadAwakened = false;
inSync = false;
lockInGui();
}
+void QQuickRenderThreadSingleContextWindowManager::handleDeferredUpdate()
+{
+#ifdef THREAD_DEBUG
+ printf("GUI: handling update to ourselves...\n");
+#endif
+
+ isDeferredUpdatePosted = false;
-void QQuickRenderThreadSingleContextWindowManager::maybeUpdate(QQuickCanvas *canvas)
+ lockInGui();
+ isExternalUpdatePending = true;
+ if (isRenderBlocked)
+ wake();
+ unlockInGui();
+}
+
+void QQuickRenderThreadSingleContextWindowManager::maybeUpdate(QQuickCanvas *)
{
Q_ASSERT_X(QThread::currentThread() == QCoreApplication::instance()->thread() || inSync,
"QQuickCanvas::update",
"Function can only be called from GUI thread or during QQuickItem::updatePaintNode()");
if (inSync) {
- CanvasData *canvasData = m_rendered_windows.value(canvas);
- if (canvasData)
- canvasData->isExternalUpdatePending = true;
+ isExternalUpdatePending = true;
- } else if (!renderThreadAwakened) {
+ } else if (!isDeferredUpdatePosted) {
#ifdef THREAD_DEBUG
- printf("GUI: doing update...\n");
+ printf("GUI: posting update to ourselves...\n");
#endif
- renderThreadAwakened = true;
-
- // If we are getting here from the renderer's sync event, the renderer is about
- // to go to sleep anyway.
- if (!isGuiAboutToBeBlockedForSync)
- lockInGui();
- CanvasData *canvasData = m_rendered_windows.value(canvas);
- if (canvasData)
- canvasData->isExternalUpdatePending = true;
- if (isRenderBlocked)
- wake();
- if (!isGuiAboutToBeBlockedForSync)
- unlockInGui();
+ isDeferredUpdatePosted = true;
+ QCoreApplication::postEvent(this, new QEvent(QEvent_DeferredUpdate));
}
+
}
QQuickTrivialWindowManager::QQuickTrivialWindowManager()