summaryrefslogtreecommitdiffstats
path: root/src/runtime/dragon
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/dragon')
-rw-r--r--src/runtime/dragon/dragonactivatedsurface.cpp10
-rw-r--r--src/runtime/dragon/dragonactivatedsurface_p.h5
-rw-r--r--src/runtime/dragon/dragonrenderer.cpp57
-rw-r--r--src/runtime/dragon/dragonrenderer_p.h16
-rw-r--r--src/runtime/dragon/qdragonrenderaspect.cpp14
-rw-r--r--src/runtime/dragon/qdragonrenderaspect_p.h5
6 files changed, 75 insertions, 32 deletions
diff --git a/src/runtime/dragon/dragonactivatedsurface.cpp b/src/runtime/dragon/dragonactivatedsurface.cpp
index 2657be9..e485759 100644
--- a/src/runtime/dragon/dragonactivatedsurface.cpp
+++ b/src/runtime/dragon/dragonactivatedsurface.cpp
@@ -420,9 +420,9 @@ void ActivatedSurface::applyUniform(const ShaderUniform &description, const Unif
}
}
-DrawContext ActivatedSurface::beginDrawing()
+DrawContext ActivatedSurface::beginDrawing(bool autoSwapBuffers)
{
- return DrawContext(m_glContext, m_surface);
+ return DrawContext(m_glContext, m_surface, autoSwapBuffers);
}
UniformValue standardUniformValue(StandardUniform standardUniformType,
@@ -1661,14 +1661,16 @@ void ActivatedSurface::blitFramebuffer(const BlitFramebufferInfo &blitFramebuffe
}
}
-DrawContext::DrawContext(QOpenGLContext *openGLContext, QSurface *surface)
+DrawContext::DrawContext(QOpenGLContext *openGLContext, QSurface *surface, bool autoSwapBuffers)
: m_openGLContext(openGLContext)
, m_surface(surface)
+ , m_autoSwapBuffers(autoSwapBuffers)
{ }
DrawContext::~DrawContext()
{
- m_openGLContext->swapBuffers(m_surface);
+ if (m_autoSwapBuffers)
+ m_openGLContext->swapBuffers(m_surface);
}
#define QT3D_DRAGON_UNIFORM_TYPE_IMPL(UniformTypeEnum, BaseType, Func) \
diff --git a/src/runtime/dragon/dragonactivatedsurface_p.h b/src/runtime/dragon/dragonactivatedsurface_p.h
index 65e8fe0..dbccf57 100644
--- a/src/runtime/dragon/dragonactivatedsurface_p.h
+++ b/src/runtime/dragon/dragonactivatedsurface_p.h
@@ -89,9 +89,10 @@ class DrawContext
public:
~DrawContext();
private:
- DrawContext(QOpenGLContext *openGLContext, QSurface *surface);
+ DrawContext(QOpenGLContext *openGLContext, QSurface *surface, bool autoSwapBuffers);
QOpenGLContext *m_openGLContext = nullptr;
QSurface *m_surface = nullptr;
+ bool m_autoSwapBuffers = true;
friend class ActivatedSurface;
};
@@ -160,7 +161,7 @@ public:
// Parameter/uniform functions
void applyUniform(const ShaderUniform &description, const UniformValue &v);
- DrawContext beginDrawing();
+ DrawContext beginDrawing(bool autoSwapBuffers);
void blitFramebuffer(const BlitFramebufferInfo &blitFramebufferInfo, uint defaultFboId, const MutableContainer<GLTexture> &glTextures);
private:
diff --git a/src/runtime/dragon/dragonrenderer.cpp b/src/runtime/dragon/dragonrenderer.cpp
index afd0089..175534c 100644
--- a/src/runtime/dragon/dragonrenderer.cpp
+++ b/src/runtime/dragon/dragonrenderer.cpp
@@ -132,10 +132,11 @@ a Renderer for each backend.
*/
-Renderer::Renderer()
+Renderer::Renderer(RenderType renderType)
: nextFrameSemaphore(1)
- , m_renderThread(new RenderThread(this))
+ , m_renderThread(renderType == Threaded ? new RenderThread(this) : nullptr)
, m_running(1)
+ , m_renderType(renderType)
{
if (m_renderThread)
m_renderThread->waitForStart();
@@ -160,20 +161,31 @@ Renderer::~Renderer()
m_renderThread->wait();
}
m_offscreenHelper->deleteLater();
+ if (m_ownedContext)
+ m_glContext->deleteLater();
}
-void Renderer::initialize()
+/*!
+ * \internal
+ * \brief Renderer::initialize
+ *
+ * If a context is provided to this function, it will be used for rendering,
+ * which is the case for Studio3D and Scene3D items.
+ */
+void Renderer::initialize(QOpenGLContext *context)
{
- // TODO don't forget to delete this
- m_glContext = new QOpenGLContext;
- m_glContext->setShareContext(qt_gl_global_share_context());
- m_glContext->create();
- // if (m_glContext->create())
- // qCDebug(Render::Backend) << "OpenGL context created with actual format"
- // << m_glContext->format();
- // else
- // qCWarning(Render::Backend) << Q_FUNC_INFO << "OpenGL context creation failed";
- m_ownedContext = true;
+ if (context != nullptr) {
+ m_glContext = context;
+ } else {
+ m_glContext = new QOpenGLContext;
+ m_glContext->setShareContext(qt_gl_global_share_context());
+
+ if (!m_glContext->create())
+ qWarning() << Q_FUNC_INFO << "OpenGL context creation failed";
+
+ m_ownedContext = true;
+ }
+
if (!m_glContext->shareContext()) {
// TODO don't forget to delete this
m_shareContext = new QOpenGLContext;
@@ -367,6 +379,8 @@ Renderer::Frame Renderer::doRender(Renderer::Frame frame)
continue;
}
+ const GLuint fboBeforeRender = activeSurface.glHelper()->boundFrameBufferObject();
+
// We only need to do preparations such as uploading textures for one surface
if (!preparationsComplete) {
{
@@ -483,6 +497,12 @@ Renderer::Frame Renderer::doRender(Renderer::Frame frame)
}
}
+ {
+ GLRenderTarget renderTarget;
+ renderTarget.frameBufferObjectId = fboBeforeRender;
+ frame.createdRenderTargets[QNodeId()] = renderTarget;
+ }
+
// Create render target
if (!view->renderTargetId.isNull()) {
auto defaultFBO = m_glContext->defaultFramebufferObject();
@@ -491,7 +511,8 @@ Renderer::Frame Renderer::doRender(Renderer::Frame frame)
auto lastBoundFBOId = activeSurface.glHelper()->boundFrameBufferObject();
const auto &renderTargetNodeId = view->renderTargetId;
const auto &attachments = view->attachmentPack;
- if (!frame.createdRenderTargets.contains(view->renderTargetId)) {
+
+ if (!frame.createdRenderTargets.contains(renderTargetNodeId)) {
GLRenderTarget renderTarget;
if (defaultFBO != 0 && lastBoundFBOId == defaultFBO) {
// this is the default fbo that some platforms create (iOS),
@@ -558,7 +579,9 @@ Renderer::Frame Renderer::doRender(Renderer::Frame frame)
if (!preparationsComplete)
return frame;
- DrawContext drawContext = activeSurface.beginDrawing();
+ // TODO might be better to just have to call swapBuffers manually
+ bool autoSwapBuffers = m_renderType == RenderType::Threaded;
+ DrawContext drawContext = activeSurface.beginDrawing(autoSwapBuffers);
// TODO consider what m_ownCurrent was used for in SubmissionContext
@@ -592,9 +615,7 @@ Renderer::Frame Renderer::doRender(Renderer::Frame frame)
// TODO handle render state set
// TODO consider having this function return a render target that is passed to the following functions
- activeSurface.activateRenderTarget(frame.createdRenderTargets[view->renderTargetId]
- .frameBufferObjectId,
- view->attachmentPack);
+ activeSurface.activateRenderTarget(frame.createdRenderTargets[view->renderTargetId].frameBufferObjectId, view->attachmentPack);
activeSurface.clearBackBuffer(view->clearBackBufferInfo);
// TODO make it return a viewport, used by other functions that need one
diff --git a/src/runtime/dragon/dragonrenderer_p.h b/src/runtime/dragon/dragonrenderer_p.h
index dc8f627..c040819 100644
--- a/src/runtime/dragon/dragonrenderer_p.h
+++ b/src/runtime/dragon/dragonrenderer_p.h
@@ -134,7 +134,7 @@ struct GLRenderTarget
class Renderer
{
-private:
+public:
/*!
* \brief The Frame struct holds data that is shared across frames,
* such as already uploaded textures and active textures.
@@ -152,8 +152,14 @@ private:
int number = 0;
};
-public:
- Renderer();
+ // TODO a cleaner option is to move all thread-specific code into a separate class
+ // instead of letting one class handle both cases
+ enum RenderType {
+ Synchronous,
+ Threaded
+ };
+
+ Renderer(RenderType renderType);
~Renderer();
void render();
@@ -163,7 +169,7 @@ public:
void addLatestData(FrameInput data);
GraphicsApiFilterData contextInfo(RenderViews views);
- void initialize();
+ void initialize(QOpenGLContext *context = nullptr);
QSemaphore nextFrameSemaphore;
@@ -206,6 +212,8 @@ private:
OffscreenSurfaceHelper *m_offscreenHelper;
+ RenderType m_renderType;
+
// // Shaders
// Render::ShaderCache *m_shaderCache = nullptr;
diff --git a/src/runtime/dragon/qdragonrenderaspect.cpp b/src/runtime/dragon/qdragonrenderaspect.cpp
index 3427068..f82c1f5 100644
--- a/src/runtime/dragon/qdragonrenderaspect.cpp
+++ b/src/runtime/dragon/qdragonrenderaspect.cpp
@@ -187,8 +187,8 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Dragon {
-QDragonRenderAspect::QDragonRenderAspect()
- : m_renderer(new Renderer())
+QDragonRenderAspect::QDragonRenderAspect(Renderer::RenderType renderType)
+ : m_renderer(new Renderer(renderType))
{
registerBackendType<Qt3DCore::QEntity>(m_entities);
registerBackendType<Qt3DCore::QTransform>(m_transforms);
@@ -512,6 +512,16 @@ QVector<Qt3DCore::QAspectJobPtr> QDragonRenderAspect::jobsToExecute(qint64 time)
return m_jobs;
}
+Renderer::Frame QDragonRenderAspect::renderSynchronous(Renderer::Frame frame)
+{
+ return m_renderer->doRender(std::move(frame));
+}
+
+void QDragonRenderAspect::initialize(QOpenGLContext *context)
+{
+ m_renderer->initialize(context);
+}
+
} // namespace Dragon
} // namespace Qt3DRender
QT_END_NAMESPACE
diff --git a/src/runtime/dragon/qdragonrenderaspect_p.h b/src/runtime/dragon/qdragonrenderaspect_p.h
index d60f759..32cb559 100644
--- a/src/runtime/dragon/qdragonrenderaspect_p.h
+++ b/src/runtime/dragon/qdragonrenderaspect_p.h
@@ -114,9 +114,10 @@ class Q3DSV_EXPORT QDragonRenderAspect : public Qt3DCore::QAbstractAspect
{
Q_OBJECT
public:
- QDragonRenderAspect();
+ QDragonRenderAspect(Renderer::RenderType renderType);
+ Renderer::Frame renderSynchronous(Renderer::Frame frame);
+ void initialize(QOpenGLContext *context);
- // QAbstractAspect interface
private:
QVector<Qt3DCore::QAspectJobPtr> jobsToExecute(qint64 time) override;