updateFocusItemTransform();
}
+/**
+ * This parameter enables that this canvas can be rendered without
+ * being shown on screen. This feature is very limited in what it supports.
+ *
+ * There needs to be another window actually showing that we can make current
+ * to get a surface to make current AND for this feature to be useful
+ * one needs to hook into beforeRender() and set the render tareget.
+ *
+ */
+void QQuickCanvasPrivate::setRenderWithoutShowing(bool render)
+{
+ if (render == renderWithoutShowing)
+ return;
+
+ Q_Q(QQuickCanvas);
+ renderWithoutShowing = render;
+
+ if (render)
+ windowManager->show(q);
+ else
+ windowManager->hide(q);
+}
+
+
void forceUpdate(QQuickItem *item)
{
if (item->flags() & QQuickItem::ItemHasContents)
: rootItem(0)
, activeFocusItem(0)
, mouseGrabberItem(0)
+ , renderWithoutShowing(false)
, dirtyItemList(0)
, context(0)
, renderer(0)
void run();
+ QQuickCanvas *masterCanvas() {
+ QQuickCanvas *win = 0;
+ for (QHash<QQuickCanvas *, CanvasData *>::const_iterator it = m_rendered_windows.constBegin();
+ it != m_rendered_windows.constEnd() && !win; ++it) {
+ if (it.value()->isVisible)
+ win = it.key();
+ }
+ return win;
+ }
+
public slots:
void animationStarted();
void animationStopped();
QSize viewportSize;
uint sizeWasChanged : 1;
+ uint isVisible : 1;
};
QHash<QQuickCanvas *, CanvasData *> m_rendered_windows;
void canvasDestroyed(QQuickCanvas *canvas);
+ void initializeGL();
void renderCanvas(QQuickCanvas *canvas);
void paint(QQuickCanvas *canvas);
QImage grab(QQuickCanvas *canvas);
void QQuickRenderThreadSingleContextWindowManager::initialize()
{
Q_ASSERT(m_rendered_windows.size());
- QQuickCanvas *win = m_rendered_windows.constBegin().key();
+
+ QQuickCanvas *win = masterCanvas();
+ if (!win)
+ return;
gl = new QOpenGLContext();
// Pick up the surface format from one of them
CanvasData *data = new CanvasData;
data->sizeWasChanged = false;
data->windowSize = canvas->size();
+ data->isVisible = canvas->visible();
m_rendered_windows[canvas] = data;
isExternalUpdatePending = true;
CanvasTracker &t = const_cast<CanvasTracker &>(m_tracked_windows.at(i));
QQuickCanvas *win = t.canvas;
- Q_ASSERT(win->visible() || t.toBeRemoved);
+ Q_ASSERT(win->visible() || QQuickCanvasPrivate::get(win)->renderWithoutShowing || t.toBeRemoved);
bool canvasVisible = win->width() > 0 && win->height() > 0;
anyoneShowing |= (canvasVisible && !t.toBeRemoved);
wake();
unlock();
+ if (!gl)
+ return;
+
while (!shouldExit) {
lock();
Q_ASSERT(canvasData->windowSize.width() > 0 && canvasData->windowSize.height() > 0);
- gl->makeCurrent(canvas);
+ if (!canvasData->isVisible)
+ gl->makeCurrent(masterCanvas());
+ else
+ gl->makeCurrent(canvas);
if (canvasData->viewportSize != canvasData->windowSize) {
#ifdef THREAD_DEBUG
printf(" RenderThread: --- wait for swap...\n");
#endif
- gl->swapBuffers(canvas);
+ if (canvasData->isVisible)
+ gl->swapBuffers(canvas);
+
canvasPrivate->fireFrameSwapped();
#ifdef THREAD_DEBUG
printf(" RenderThread: --- swap complete...\n");
CanvasData &data = const_cast<CanvasData &>(m_windows[canvas]);
+ QQuickCanvas *masterCanvas = 0;
+ if (!canvas->visible()) {
+ // Find a "proper surface" to bind...
+ for (QHash<QQuickCanvas *, CanvasData>::const_iterator it = m_windows.constBegin();
+ it != m_windows.constEnd() && !masterCanvas; ++it) {
+ if (it.key()->visible())
+ masterCanvas = it.key();
+ }
+ } else {
+ masterCanvas = canvas;
+ }
+
+ if (!masterCanvas)
+ return;
+
if (!gl) {
gl = new QOpenGLContext();
- gl->setFormat(canvas->requestedFormat());
+ gl->setFormat(masterCanvas->requestedFormat());
gl->create();
- if (!gl->makeCurrent(canvas))
+ if (!gl->makeCurrent(masterCanvas))
qWarning("QQuickCanvas: makeCurrent() failed...");
sg->initialize(gl);
} else {
- gl->makeCurrent(canvas);
+ gl->makeCurrent(masterCanvas);
}
bool alsoSwap = data.updatePending;
data.grabOnly = false;
}
- if (alsoSwap) {
+ if (alsoSwap && canvas->visible()) {
gl->swapBuffers(canvas);
cd->fireFrameSwapped();
}