Document and demo that fboId can be 0

...in QQuickWindow::setRenderTarget().

The rendercontrol example is extended with a --onscreen
command line argument that can be used to request rendering
to the default framebuffer of the window.

Change-Id: I7a500d1585dee8334b902fb1dddcb1cb21a2e038
Task-number: QTBUG-59340
Reviewed-by: Gunnar Sletta <gunnar@crimson.no>
This commit is contained in:
Laszlo Agocs 2017-03-07 19:52:34 +01:00
parent e7a6544225
commit 13fc05fde8
3 changed files with 44 additions and 9 deletions

View File

@ -82,6 +82,10 @@ WindowSingleThreaded::WindowSingleThreaded()
{
setSurfaceType(QSurface::OpenGLSurface);
// The rendercontrol does not necessarily need an FBO. Demonstrate this
// when requested.
m_onscreen = QCoreApplication::arguments().contains(QStringLiteral("--onscreen"));
QSurfaceFormat format;
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
format.setDepthBufferSize(16);
@ -164,8 +168,14 @@ void WindowSingleThreaded::createFbo()
// The scene graph has been initialized. It is now time to create an FBO and associate
// it with the QQuickWindow.
m_dpr = devicePixelRatio();
m_fbo = new QOpenGLFramebufferObject(size() * m_dpr, QOpenGLFramebufferObject::CombinedDepthStencil);
m_quickWindow->setRenderTarget(m_fbo);
if (!m_onscreen) {
m_fbo = new QOpenGLFramebufferObject(size() * m_dpr, QOpenGLFramebufferObject::CombinedDepthStencil);
m_quickWindow->setRenderTarget(m_fbo);
} else {
// Special case: No FBO. Render directly to the window's default framebuffer.
m_onscreenSize = size() * m_dpr;
m_quickWindow->setRenderTarget(0, m_onscreenSize);
}
}
void WindowSingleThreaded::destroyFbo()
@ -176,7 +186,10 @@ void WindowSingleThreaded::destroyFbo()
void WindowSingleThreaded::render()
{
if (!m_context->makeCurrent(m_offscreenSurface))
QSurface *surface = m_offscreenSurface;
if (m_onscreen)
surface = this;
if (!m_context->makeCurrent(surface))
return;
// Polish, synchronize and render the next frame (into our fbo). In this example
@ -195,7 +208,10 @@ void WindowSingleThreaded::render()
m_quickReady = true;
// Get something onto the screen.
m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
if (!m_onscreen)
m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
else
m_context->swapBuffers(this);
}
void WindowSingleThreaded::requestUpdate()
@ -237,7 +253,10 @@ void WindowSingleThreaded::run()
updateSizes();
// Initialize the render control and our OpenGL resources.
m_context->makeCurrent(m_offscreenSurface);
QSurface *surface = m_offscreenSurface;
if (m_onscreen)
surface = this;
m_context->makeCurrent(surface);
m_renderControl->initialize(m_context);
m_quickInitialized = true;
}
@ -266,7 +285,8 @@ void WindowSingleThreaded::exposeEvent(QExposeEvent *)
{
if (isExposed()) {
if (!m_quickInitialized) {
m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
if (!m_onscreen)
m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
startQuick(QStringLiteral("qrc:/rendercontrol/demo.qml"));
}
}
@ -274,7 +294,10 @@ void WindowSingleThreaded::exposeEvent(QExposeEvent *)
void WindowSingleThreaded::resizeFbo()
{
if (m_rootItem && m_context->makeCurrent(m_offscreenSurface)) {
QSurface *surface = m_offscreenSurface;
if (m_onscreen)
surface = this;
if (m_rootItem && m_context->makeCurrent(surface)) {
delete m_fbo;
createFbo();
m_context->doneCurrent();
@ -287,8 +310,13 @@ void WindowSingleThreaded::resizeEvent(QResizeEvent *)
{
// If this is a resize after the scene is up and running, recreate the fbo and the
// Quick item and scene.
if (m_fbo && m_fbo->size() != size() * devicePixelRatio())
resizeFbo();
if (!m_onscreen) {
if (m_fbo && m_fbo->size() != size() * devicePixelRatio())
resizeFbo();
} else {
if (m_onscreenSize != size() * devicePixelRatio())
resizeFbo();
}
}
void WindowSingleThreaded::handleScreenChange()

View File

@ -97,6 +97,8 @@ private:
QTimer m_updateTimer;
CubeRenderer *m_cubeRenderer;
qreal m_dpr;
bool m_onscreen;
QSize m_onscreenSize;
};
#endif

View File

@ -3399,6 +3399,11 @@ void QQuickWindow::setRenderTarget(QOpenGLFramebufferObject *fbo)
The specified FBO must be created in the context of the window
or one that shares with it.
\note \a fboId can also be set to 0. In this case rendering will target the
default framebuffer of whichever surface is current when the scenegraph
renders. \a size must still be valid, specifying the dimensions of the
surface.
\note
This function only has an effect when using the default OpenGL scene
graph adaptation.