uniformBufferManager.reset(new Render::UniformBufferManager(&graphicsController));
// initialize main command buffer
- auto info = Graphics::CommandBufferCreateInfo().SetLevel( Graphics::CommandBufferLevel::PRIMARY );
- mainCommandBuffer = graphicsController.CreateCommandBuffer( info, nullptr );
+ auto info = Graphics::CommandBufferCreateInfo().SetLevel(Graphics::CommandBufferLevel::PRIMARY);
+ mainCommandBuffer = graphicsController.CreateCommandBuffer(info, nullptr);
}
~Impl()
Graphics::UniquePtr<Graphics::CommandBuffer> mainCommandBuffer; ///< Main command buffer
Graphics::UniquePtr<Graphics::RenderPass> mainRenderPass; ///< Main renderpass
-
-
};
RenderManager* RenderManager::New(Graphics::Controller& graphicsController,
void RenderManager::InitializeScene(SceneGraph::Scene* scene)
{
- scene->Initialize(*mImpl->CreateSceneContext());
+ scene->Initialize(*mImpl->CreateSceneContext(), mImpl->graphicsController);
mImpl->sceneContainer.push_back(scene);
}
void RenderManager::SurfaceReplaced(SceneGraph::Scene* scene)
{
Context* newContext = mImpl->ReplaceSceneContext(scene->GetContext());
- scene->Initialize(*newContext);
+ scene->Initialize(*newContext, mImpl->graphicsController);
}
void RenderManager::AttachColorTextureToFrameBuffer(Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer)
{
mImpl->currentContext = &mImpl->context;
- if(mImpl->currentContext->IsSurfacelessContextSupported())
- {
- mImpl->graphicsController.GetGlContextHelperAbstraction().MakeSurfacelessContextCurrent();
- }
+ // Context switch now happens when the uploading happens in graphics side
+ // if(mImpl->currentContext->IsSurfacelessContextSupported())
+ // {
+ // mImpl->graphicsController.GetGlContextHelperAbstraction().MakeSurfacelessContextCurrent();
+ // }
// Clear the current cached program when the context is switched
mImpl->programController.ClearCurrentProgram();
// todo: use no-clear renderpass instead (not implemented yet)
// Set the clear color for first color attachment
- if( instruction.mIsClearColorSet )
+ if(instruction.mIsClearColorSet)
{
clearValues[0].color = {
instruction.mClearColor.r,
instruction.mClearColor.g,
instruction.mClearColor.b,
- instruction.mClearColor.a
- };
+ instruction.mClearColor.a};
}
// offscreen buffer
mainCommandBuffer->BeginRenderPass(
- instruction.mFrameBuffer->GetGraphicsRenderPass( Graphics::AttachmentLoadOp::CLEAR, Graphics::AttachmentStoreOp::STORE ),
+ instruction.mFrameBuffer->GetGraphicsRenderPass(Graphics::AttachmentLoadOp::CLEAR, Graphics::AttachmentStoreOp::STORE),
instruction.mFrameBuffer->GetGraphicsRenderTarget(),
- { instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight() },
- clearValues
- );
+ {instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight()},
+ clearValues);
if(mImpl->currentContext != &mImpl->context)
{
// Switch to shared context for off-screen buffer
mImpl->currentContext = &mImpl->context;
- if(mImpl->currentContext->IsSurfacelessContextSupported())
- {
- mImpl->graphicsController.GetGlContextHelperAbstraction().MakeSurfacelessContextCurrent();
- }
+ // Context switch now happens when render pass starts
+ // if(mImpl->currentContext->IsSurfacelessContextSupported())
+ // {
+ // mImpl->graphicsController.GetGlContextHelperAbstraction().MakeSurfacelessContextCurrent();
+ // }
// Clear the current cached program when the context is switched
mImpl->programController.ClearCurrentProgram();
mImpl->programController.ClearCurrentProgram();
}
}
+
+ // surface
+ auto& clearValues = sceneObject->GetGraphicsRenderPassClearValues();
+
+ if(instruction.mIsClearColorSet)
+ {
+ clearValues[0].color = {
+ instruction.mClearColor.r,
+ instruction.mClearColor.g,
+ instruction.mClearColor.b,
+ instruction.mClearColor.a};
+ }
+
+ mainCommandBuffer->BeginRenderPass(
+ sceneObject->GetGraphicsRenderPass(),
+ sceneObject->GetSurfaceRenderTarget(),
+ {static_cast<uint32_t>(surfaceRect.width), static_cast<uint32_t>(surfaceRect.height)},
+ clearValues);
}
// Make sure that GL context must be created
if(instruction.mFrameBuffer)
{
-
//instruction.mFrameBuffer->Bind(*mImpl->currentContext);
// @todo Temporarily set per renderer per pipeline. Should use RenderPass instead
}
else
{
- mImpl->currentContext->BindFramebuffer(GL_FRAMEBUFFER, 0u);
+ //mImpl->currentContext->BindFramebuffer(GL_FRAMEBUFFER, 0u);
}
// @todo Should this be a command in it's own right?
// @todo yes
if(!instruction.mFrameBuffer)
{
+ /*
mImpl->currentContext->Viewport(surfaceRect.x,
surfaceRect.y,
surfaceRect.width,
surfaceRect.height);
+ */
+
/*
mainCommandBuffer->SetViewport( {surfaceRect.x,
surfaceRect.y,
// It is important to clear all 3 buffers when they are being used, for performance on deferred renderers
// e.g. previously when the depth & stencil buffers were NOT cleared, it caused the DDK to exceed a "vertex count limit",
// and then stall. That problem is only noticeable when rendering a large number of vertices per frame.
+
+ /*
GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
mImpl->currentContext->ColorMask(true);
mImpl->currentContext->StencilMask(0xFF); // 8 bit stencil mask, all 1's
clearMask |= GL_STENCIL_BUFFER_BIT;
}
-
+ */
if(!instruction.mIgnoreRenderToFbo && (instruction.mFrameBuffer != nullptr))
{
// Offscreen buffer rendering
// @todo The following block should be a command in it's own right.
// Currently takes account of surface orientation in Context.
// Or move entirely to RenderPass implementation
- mImpl->currentContext->Viewport(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height);
+ mainCommandBuffer->SetViewport( {
+ float(viewportRect.x),
+ float(viewportRect.y),
+ float(viewportRect.width),
+ float(viewportRect.height)} );
+
+ //mImpl->currentContext->Viewport(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height);
if(instruction.mIsClearColorSet)
{
- mImpl->currentContext->ClearColor(clearColor.r,
- clearColor.g,
- clearColor.b,
- clearColor.a);
if(!clearFullFrameRect)
{
if(!clippingRect.IsEmpty())
{
- mImpl->currentContext->SetScissorTest(true);
- mImpl->currentContext->Scissor(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height);
- mImpl->currentContext->Clear(clearMask, Context::FORCE_CLEAR);
- mImpl->currentContext->SetScissorTest(false);
+ //mImpl->currentContext->SetScissorTest(true);
+ //mImpl->currentContext->Scissor(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height);
+ //mImpl->currentContext->Clear(clearMask, Context::FORCE_CLEAR);
+ //mImpl->currentContext->SetScissorTest(false);
}
else
{
- mImpl->currentContext->SetScissorTest(true);
- mImpl->currentContext->Scissor(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height);
- mImpl->currentContext->Clear(clearMask, Context::FORCE_CLEAR);
- mImpl->currentContext->SetScissorTest(false);
+ //mImpl->currentContext->SetScissorTest(true);
+ //mImpl->currentContext->Scissor(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height);
+ //mImpl->currentContext->Clear(clearMask, Context::FORCE_CLEAR);
+ //mImpl->currentContext->SetScissorTest(false);
}
}
else
{
- mImpl->currentContext->SetScissorTest(false);
- mImpl->currentContext->Clear(clearMask, Context::FORCE_CLEAR);
+ //mImpl->currentContext->SetScissorTest(false);
+ //mImpl->currentContext->Clear(clearMask, Context::FORCE_CLEAR);
}
}
instruction.mRenderTracker = nullptr; // Only create once.
}
- if(renderToFbo)
- {
- mImpl->currentContext->Flush();
- }
+ // This now happens when the render pass for frame buffer finishes
+ // if(renderToFbo)
+ // {
+ // mImpl->currentContext->Flush();
+ // }
// End render pass
mainCommandBuffer->EndRenderPass();
if(!uploadOnly)
{
- if(mImpl->currentContext->IsSurfacelessContextSupported())
- {
- mImpl->graphicsController.GetGlContextHelperAbstraction().MakeSurfacelessContextCurrent();
- }
+ // Context switch now happens outside the render manager
+ // if(mImpl->currentContext->IsSurfacelessContextSupported())
+ // {
+ // mImpl->graphicsController.GetGlContextHelperAbstraction().MakeSurfacelessContextCurrent();
+ // }
GLenum attachments[] = {GL_DEPTH, GL_STENCIL};
mImpl->context.InvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments);
*/
// INTERNAL INCLUDES
+#include <dali/graphics-api/graphics-controller.h>
#include <dali/integration-api/scene.h>
#include <dali/internal/common/message.h>
#include <dali/internal/event/common/event-thread-services.h>
/**
* Creates a scene object in the GPU.
* @param[in] context The GL context
+ * @param[in] graphicsController The graphics controller
*/
- void Initialize(Context& context);
+ void Initialize(Context& context, Graphics::Controller& graphicsController);
/**
* Gets the context holding the GL state of rendering for the scene
*/
bool IsSurfaceRectChanged();
+ /**
+ * Set the render target of the surface
+ *
+ * @param[in] renderTarget The render target.
+ */
+ void SetSurfaceRenderTarget(Graphics::RenderTarget* renderTarget)
+ {
+ mRenderTarget = renderTarget;
+ }
+
+ /**
+ * Get the render target created for the scene
+ *
+ * @return the render target
+ */
+ [[nodiscard]] Graphics::RenderTarget* GetSurfaceRenderTarget() const
+ {
+ return mRenderTarget;
+ }
+
+ /**
+ * Get the graphics render pass created for the scene
+ *
+ * @return the graphics render pass
+ */
+ [[nodiscard]] Graphics::RenderPass* GetGraphicsRenderPass() const
+ {
+ return mRenderPass.get();
+ }
+
+ /**
+ * Get an initialized array of clear values which then can be modified and accessed to BeginRenderPass() command.
+ *
+ * @return the array of clear values
+ */
+ [[nodiscard]] auto& GetGraphicsRenderPassClearValues()
+ {
+ return mClearValues;
+ }
+
private:
Context* mContext; ///< The context holding the GL state of rendering for the scene, not owned
Rect<int32_t> mSurfaceRect; ///< The rectangle of surface which is related ot this scene.
int32_t mSurfaceOrientation; ///< The orientation of surface which is related of this scene
bool mSurfaceRectChanged; ///< The flag of surface's rectangle is changed when is resized, moved or rotated.
+
+ // Render pass and render target
+
+ /**
+ * Render pass is created on fly depending on Load and Store operations
+ * The default render pass (most likely to be used) is the load = CLEAR
+ * and store = STORE for color attachment.
+ */
+ Graphics::UniquePtr<Graphics::RenderPass> mRenderPass{nullptr}; ///< The render pass created to render the surface
+ Graphics::RenderTarget* mRenderTarget{nullptr}; ///< This is created in the event thread when surface is created/resized/replaced
+
+ // clear colors
+ std::vector<Graphics::ClearValue> mClearValues{};
};
/// Messages
new(slot) LocalType(&scene, &Scene::SetSurfaceOrientation, orientation);
}
+inline void SetSurfaceRenderTargetMessage(EventThreadServices& eventThreadServices, const Scene& scene, Graphics::RenderTarget* renderTarget)
+{
+ using LocalType = MessageValue1<Scene, Graphics::RenderTarget*>;
+
+ // Reserve some memory inside the message queue
+ uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
+
+ // Construct message in the message queue memory; note that delete should not be called on the return value
+ new(slot) LocalType(&scene, &Scene::SetSurfaceRenderTarget, renderTarget);
+}
+
} // namespace SceneGraph
} // namespace Internal