RenderPass and presentation 78/256578/6
authoradam.b <adam.b@samsung.com>
Wed, 7 Apr 2021 11:42:13 +0000 (12:42 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Tue, 13 Apr 2021 10:58:17 +0000 (11:58 +0100)
Change-Id: I5630cb63e25b86a065001d8879b88537489ff2b8

automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h
dali/graphics-api/graphics-command-buffer.h
dali/internal/render/common/render-manager.cpp
dali/internal/update/common/scene-graph-scene.cpp
dali/internal/update/common/scene-graph-scene.h

index 79d0f1b..bc1ea7b 100644 (file)
@@ -467,7 +467,7 @@ struct Command
     {
       Graphics::RenderPass*             renderPass;
       Graphics::RenderTarget*           renderTarget;
-      Graphics::Extent2D                renderArea;
+      Graphics::Rect2D                  renderArea;
       std::vector<Graphics::ClearValue> clearValues;
     } beginRenderPass;
 
@@ -593,7 +593,7 @@ public:
   void BeginRenderPass(
     Graphics::RenderPass*             renderPass,
     Graphics::RenderTarget*           renderTarget,
-    Graphics::Extent2D                renderArea,
+    Graphics::Rect2D                  renderArea,
     std::vector<Graphics::ClearValue> clearValues) override
   {
     mCommands.emplace_back(CommandType::BEGIN_RENDER_PASS);
index 7056e47..9ba466b 100644 (file)
@@ -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<ClearValue> clearValues) = 0;
 
   /**
index a699135..f58e2d1 100644 (file)
@@ -809,6 +809,8 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
 
   uint32_t count = sceneObject->GetRenderInstructions().Count(mImpl->renderBufferIndex);
 
+  std::vector<Graphics::RenderTarget*> 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<Graphics::ClearValue> 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<uint32_t>(surfaceRect.width), static_cast<uint32_t>(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);
 }
index a4fb196..e6f7fa1 100644 (file)
@@ -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()
index b41dd22..04411ae 100644 (file)
@@ -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<Graphics::RenderPass> mRenderPass{nullptr};   ///< The render pass created to render the surface
+  Graphics::UniquePtr<Graphics::RenderPass> 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