diff options
Diffstat (limited to 'src/runtime/dragon')
-rw-r--r-- | src/runtime/dragon/dragonactivatedsurface.cpp | 10 | ||||
-rw-r--r-- | src/runtime/dragon/dragonactivatedsurface_p.h | 5 | ||||
-rw-r--r-- | src/runtime/dragon/dragonrenderer.cpp | 57 | ||||
-rw-r--r-- | src/runtime/dragon/dragonrenderer_p.h | 16 | ||||
-rw-r--r-- | src/runtime/dragon/qdragonrenderaspect.cpp | 14 | ||||
-rw-r--r-- | src/runtime/dragon/qdragonrenderaspect_p.h | 5 |
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; |