From 91343eea04619b8860a10a4023ea7adb989a646a Mon Sep 17 00:00:00 2001 From: "adam.b" Date: Wed, 7 Apr 2021 12:42:13 +0100 Subject: [PATCH] RenderPass and presentation Change-Id: I5630cb63e25b86a065001d8879b88537489ff2b8 --- .../test-graphics-command-buffer.h | 4 +- dali/graphics-api/graphics-command-buffer.h | 4 +- dali/internal/render/common/render-manager.cpp | 54 ++++++++++++++++++---- dali/internal/update/common/scene-graph-scene.cpp | 4 ++ dali/internal/update/common/scene-graph-scene.h | 12 ++++- 5 files changed, 62 insertions(+), 16 deletions(-) diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h index 79d0f1b..bc1ea7b 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h @@ -467,7 +467,7 @@ struct Command { Graphics::RenderPass* renderPass; Graphics::RenderTarget* renderTarget; - Graphics::Extent2D renderArea; + Graphics::Rect2D renderArea; std::vector clearValues; } beginRenderPass; @@ -593,7 +593,7 @@ public: void BeginRenderPass( Graphics::RenderPass* renderPass, Graphics::RenderTarget* renderTarget, - Graphics::Extent2D renderArea, + Graphics::Rect2D renderArea, std::vector clearValues) override { mCommands.emplace_back(CommandType::BEGIN_RENDER_PASS); diff --git a/dali/graphics-api/graphics-command-buffer.h b/dali/graphics-api/graphics-command-buffer.h index 7056e47..9ba466b 100644 --- a/dali/graphics-api/graphics-command-buffer.h +++ b/dali/graphics-api/graphics-command-buffer.h @@ -179,13 +179,13 @@ public: * @param[in] renderPass valid render pass object * @param[in] renderTarget valid render target, must not be used when framebuffer set * @param[in] framebuffer valid framebuffer, must not be used with renderTarget - * @param[in] renderArea area to draw + * @param[in] renderArea area to draw (clear operation is affected) * @param[in] clearValues clear values (compatible with renderpass spec) */ virtual void BeginRenderPass( RenderPass* renderPass, RenderTarget* renderTarget, - Extent2D renderArea, + Rect2D renderArea, std::vector clearValues) = 0; /** diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index a699135..f58e2d1 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -809,6 +809,8 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: uint32_t count = sceneObject->GetRenderInstructions().Count(mImpl->renderBufferIndex); + std::vector targetstoPresent; + for(uint32_t i = 0; i < count; ++i) { RenderInstruction& instruction = sceneObject->GetRenderInstructions().At(mImpl->renderBufferIndex, i); @@ -839,6 +841,10 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable; Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable; + Graphics::RenderTarget* currentRenderTarget = nullptr; + Graphics::RenderPass* currentRenderPass = nullptr; + std::vector currentClearValues {}; + if(instruction.mFrameBuffer) { // Ensure graphics framebuffer is created, bind atachments and create render passes @@ -864,14 +870,14 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: instruction.mClearColor.b, instruction.mClearColor.a}; } + + currentClearValues = clearValues; + auto loadOp = instruction.mIsClearColorSet ? Graphics::AttachmentLoadOp::CLEAR : Graphics::AttachmentLoadOp::LOAD; // offscreen buffer - mainCommandBuffer->BeginRenderPass( - instruction.mFrameBuffer->GetGraphicsRenderPass(loadOp, Graphics::AttachmentStoreOp::STORE), - instruction.mFrameBuffer->GetGraphicsRenderTarget(), - {instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight()}, - clearValues); + currentRenderTarget = instruction.mFrameBuffer->GetGraphicsRenderTarget(); + currentRenderPass = instruction.mFrameBuffer->GetGraphicsRenderPass(loadOp, Graphics::AttachmentStoreOp::STORE); if(mImpl->currentContext != &mImpl->context) { @@ -914,13 +920,16 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: instruction.mClearColor.a}; } - mainCommandBuffer->BeginRenderPass( - sceneObject->GetGraphicsRenderPass(), - sceneObject->GetSurfaceRenderTarget(), - {static_cast(surfaceRect.width), static_cast(surfaceRect.height)}, - clearValues); + currentClearValues = clearValues; + + auto loadOp = instruction.mIsClearColorSet ? Graphics::AttachmentLoadOp::CLEAR : Graphics::AttachmentLoadOp::LOAD; + + currentRenderTarget = sceneObject->GetSurfaceRenderTarget(); + currentRenderPass = sceneObject->GetGraphicsRenderPass(loadOp, Graphics::AttachmentStoreOp::STORE); } + targetstoPresent.emplace_back( currentRenderTarget ); + // Make sure that GL context must be created mImpl->currentContext->GlContextCreated(); @@ -1039,6 +1048,16 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: clearFullFrameRect = false; } + // Begin render pass + mainCommandBuffer->BeginRenderPass( + currentRenderPass, + currentRenderTarget, + { + viewportRect.x, viewportRect.y, + uint32_t(viewportRect.width), uint32_t(viewportRect.height) + }, + currentClearValues); + // @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 @@ -1054,6 +1073,9 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: { if(!clippingRect.IsEmpty()) { + Graphics::Rect2D scissorArea = {clippingRect.x, clippingRect.y, uint32_t(clippingRect.width), uint32_t(clippingRect.height)}; + mainCommandBuffer->SetScissor( scissorArea ); + mainCommandBuffer->SetScissorTestEnable( true ); //mImpl->currentContext->SetScissorTest(true); //mImpl->currentContext->Scissor(clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height); //mImpl->currentContext->Clear(clearMask, Context::FORCE_CLEAR); @@ -1164,6 +1186,18 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: } mImpl->renderAlgorithms.SubmitCommandBuffer(); + std::sort( targetstoPresent.begin(), targetstoPresent.end() ); + + Graphics::RenderTarget* rt = nullptr; + for( auto& target : targetstoPresent ) + { + if(target != rt) + { + mImpl->graphicsController.PresentRenderTarget(target); + rt = target; + } + } + GLenum attachments[] = {GL_DEPTH, GL_STENCIL}; mImpl->currentContext->InvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments); } diff --git a/dali/internal/update/common/scene-graph-scene.cpp b/dali/internal/update/common/scene-graph-scene.cpp index a4fb196..e6f7fa1 100644 --- a/dali/internal/update/common/scene-graph-scene.cpp +++ b/dali/internal/update/common/scene-graph-scene.cpp @@ -64,6 +64,10 @@ void Scene::Initialize(Context& context, Graphics::Controller& graphicsControlle // Add default render pass (loadOp = clear) mRenderPass = graphicsController.CreateRenderPass(rpInfo, nullptr); + + desc.SetLoadOp( Graphics::AttachmentLoadOp::LOAD ); + attachmentDescriptions[0] = desc; + mRenderPassNoClear = graphicsController.CreateRenderPass(rpInfo, nullptr); } Context* Scene::GetContext() diff --git a/dali/internal/update/common/scene-graph-scene.h b/dali/internal/update/common/scene-graph-scene.h index b41dd22..04411ae 100644 --- a/dali/internal/update/common/scene-graph-scene.h +++ b/dali/internal/update/common/scene-graph-scene.h @@ -187,9 +187,16 @@ public: * * @return the graphics render pass */ - [[nodiscard]] Graphics::RenderPass* GetGraphicsRenderPass() const + [[nodiscard]] Graphics::RenderPass* GetGraphicsRenderPass(Graphics::AttachmentLoadOp loadOp, Graphics::AttachmentStoreOp storeOp) const { - return mRenderPass.get(); + if(loadOp == Graphics::AttachmentLoadOp::CLEAR) + { + return mRenderPass.get(); + } + else + { + return mRenderPassNoClear.get(); + } } /** @@ -227,6 +234,7 @@ private: * and store = STORE for color attachment. */ Graphics::UniquePtr mRenderPass{nullptr}; ///< The render pass created to render the surface + Graphics::UniquePtr mRenderPassNoClear{nullptr}; ///< The render pass created to render the surface without clearing color Graphics::RenderTarget* mRenderTarget{nullptr}; ///< This is created in the event thread when surface is created/resized/replaced // clear colors -- 2.7.4