[Tizen] Make possible to capture on the old driver devices. 56/306156/1 accepted/tizen/7.0/unified/20240219.160848
authorseungho <sbsh.baek@samsung.com>
Tue, 23 Mar 2021 12:16:46 +0000 (21:16 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Fri, 16 Feb 2024 09:11:55 +0000 (18:11 +0900)
Change-Id: I5d20b4c70b6da1e98b0c29d465a8a700c2a0410a
Signed-off-by: seungho <sbsh.baek@samsung.com>
13 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp
automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h
dali/graphics-api/graphics-controller.h
dali/internal/event/rendering/frame-buffer-impl.cpp
dali/internal/event/rendering/frame-buffer-impl.h
dali/internal/render/common/render-manager.cpp
dali/internal/render/common/render-manager.h
dali/internal/render/renderers/render-frame-buffer.cpp
dali/internal/render/renderers/render-frame-buffer.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/public-api/rendering/frame-buffer.cpp
dali/public-api/rendering/frame-buffer.h

index 04d193c..d41d690 100644 (file)
@@ -1330,4 +1330,9 @@ bool TestGraphicsController::GetProgramParameter(Graphics::Program& program, uin
   return graphicsProgram->GetParameter(parameterId, outData);
 }
 
+void TestGraphicsController::CaptureRenderingResult(Graphics::Framebuffer& framebuffer, CallbackBase* capturedCallback, uint8_t* capturedBuffer)
+{
+  mCallStack.PushCall("CaptureRenderingResult", "");
+}
+
 } // namespace Dali
index 81b93d2..4615af2 100644 (file)
@@ -373,6 +373,8 @@ public:
    */
   bool PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const override;
 
+  void CaptureRenderingResult(Graphics::Framebuffer& framebuffer, CallbackBase* capturedCallback, uint8_t* capturedBuffer) override;
+
 public: // Test Functions
   void SetVertexFormats(Property::Array& vfs)
   {
index bba245a..ca521d7 100644 (file)
@@ -380,6 +380,9 @@ public:
    */
   virtual bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) = 0;
 
+public: // Framebuffer Capture
+  virtual void CaptureRenderingResult(Graphics::Framebuffer& framebuffer, CallbackBase* capturedCallback, uint8_t* capturedBuffer) = 0;
+
 protected:
   /**
    * Creates controller
index bd6b118..a9aa008 100644 (file)
@@ -127,6 +127,16 @@ Texture* FrameBuffer::GetDepthStencilTexture() const
   return (mStencil) ? mStencil.Get() : nullptr;
 }
 
+uint8_t* FrameBuffer::GetRenderedBuffer()
+{
+  return mRenderObject->GetRenderedBuffer();
+}
+
+void FrameBuffer::CaptureRenderedResult()
+{
+  CaptureRenderingResult(mEventThreadServices.GetUpdateManager(), *mRenderObject);
+}
+
 void FrameBuffer::SetSize(uint32_t width, uint32_t height)
 {
   mWidth  = width;
index 9066334..f2aa2b7 100644 (file)
@@ -104,6 +104,18 @@ public:
   Texture* GetDepthStencilTexture() const;
 
   /**
+   * @brief Retrieve captured buffer
+   *
+   * @return a pointer of the buffer.
+   */
+  uint8_t* GetRenderedBuffer();
+
+  /**
+   * @copydoc Dali::FrameBuffer::CaptureRenderedResult()
+   */
+  void CaptureRenderedResult();
+
+  /**
    * @brief Sets the frame buffer size.
    * @param[in] width The width size
    * @param[in] height The height size
index 2590551..6a77d9b 100644 (file)
@@ -354,6 +354,11 @@ void RenderManager::SetMultiSamplingLevelToFrameBuffer(Render::FrameBuffer* fram
   frameBuffer->SetMultiSamplingLevel(multiSamplingLevel);
 }
 
+void RenderManager::CaptureRenderingResult(Render::FrameBuffer* frameBuffer)
+{
+  frameBuffer->CaptureRenderingResult();
+}
+
 void RenderManager::AddVertexBuffer(OwnerPointer<Render::VertexBuffer>& vertexBuffer)
 {
   mImpl->vertexBufferContainer.PushBack(vertexBuffer.Release());
index 8ffb02b..9f94270 100644 (file)
@@ -298,6 +298,12 @@ public:
   void SetMultiSamplingLevelToFrameBuffer(Render::FrameBuffer* frameBuffer, uint8_t multiSamplingLevel);
 
   /**
+   * Request to capture rendered result
+   * @param[in] frameBuffer The FrameBuffer
+   */
+  void CaptureRenderingResult(Render::FrameBuffer* frameBuffer);
+
+  /**
    * Initializes a Scene to the render manager
    * @param[in] scene The Scene to initialize
    */
index 25209a9..3e99e2d 100644 (file)
@@ -30,6 +30,9 @@ namespace Render
 FrameBuffer::FrameBuffer(uint32_t width, uint32_t height, Mask attachments)
 : mWidth(width),
   mHeight(height),
+  mRenderedBuffer(nullptr),
+  mCaptureRenderedResult(false),
+  mCaptured(false),
   mDepthBuffer(attachments & Dali::FrameBuffer::Attachment::DEPTH),
   mStencilBuffer(attachments & Dali::FrameBuffer::Attachment::STENCIL)
 {
@@ -45,7 +48,13 @@ FrameBuffer::FrameBuffer(uint32_t width, uint32_t height, Mask attachments)
   }
 }
 
-FrameBuffer::~FrameBuffer() = default;
+FrameBuffer::~FrameBuffer()
+{
+  if(mRenderedBuffer != nullptr)
+  {
+    delete[] mRenderedBuffer;
+  }
+}
 
 void FrameBuffer::Destroy()
 {
@@ -124,6 +133,13 @@ bool FrameBuffer::CreateGraphicsObjects()
     {
       mGraphicsObject = mGraphicsController->CreateFramebuffer(mCreateInfo, std::move(mGraphicsObject));
 
+      if(mCaptureRenderedResult)
+      {
+        mCaptureRenderedCallback.reset(MakeCallback(this, &FrameBuffer::DrawRenderedBuffer));
+        mGraphicsController->CaptureRenderingResult(*mGraphicsObject, mCaptureRenderedCallback.get(), mRenderedBuffer);
+        mCaptureRenderedResult = false;
+      }
+
       // Create render target
       Graphics::RenderTargetCreateInfo rtInfo{};
       rtInfo
@@ -204,6 +220,46 @@ uint32_t FrameBuffer::GetHeight() const
   }
 }
 
+void FrameBuffer::DrawRenderedBuffer(uint8_t* inputBuffer)
+{
+  mCaptured = true;
+  mCaptureRenderedCallback.reset();
+}
+
+uint8_t* FrameBuffer::GetRenderedBuffer()
+{
+  if(mCaptured)
+  {
+    return mRenderedBuffer;
+  }
+  else
+  {
+    return nullptr;
+  }
+}
+
+void FrameBuffer::CaptureRenderingResult()
+{
+  if(mRenderedBuffer == nullptr)
+  {
+    mRenderedBuffer = new uint8_t[mWidth * mHeight * sizeof(uint8_t) * 4u];
+  }
+
+  // Reset captured flag
+  mCaptured = false;
+
+  if(mGraphicsObject)
+  {
+    mCaptureRenderedCallback.reset(MakeCallback(this, &FrameBuffer::DrawRenderedBuffer));
+    mGraphicsController->CaptureRenderingResult(*mGraphicsObject, mCaptureRenderedCallback.get(), mRenderedBuffer);
+  }
+  else
+  {
+    mCaptureRenderedResult = true;
+  }
+}
+
+
 } // namespace Render
 
 } // namespace Internal
index 097e703..64ca67a 100644 (file)
@@ -142,6 +142,22 @@ public:
                                                             Graphics::AttachmentStoreOp colorStoreOp) const;
 
   /**
+   * @brief Read render result
+   */
+  void DrawRenderedBuffer(uint8_t* inputBuffer);
+
+  /**
+   * @brief Retrieve rendered buffer.
+   * @return Buffer pointer
+   */
+  uint8_t* GetRenderedBuffer();
+
+  /**
+   * @brief Request to Read rendered result.
+   */
+  void CaptureRenderingResult();
+
+  /**
    * The function returns initialized array of clear values
    * which then can be modified and assed to BeginRenderPass()
    * command.
@@ -184,6 +200,12 @@ private:
   uint32_t mWidth;
   uint32_t mHeight;
 
+  std::unique_ptr<CallbackBase> mCaptureRenderedCallback;
+
+  uint8_t* mRenderedBuffer;
+  bool     mCaptureRenderedResult;
+  bool     mCaptured;
+
   bool mDepthBuffer;
   bool mStencilBuffer;
 };
index 8c540ad..584586d 100644 (file)
@@ -1551,6 +1551,17 @@ void UpdateManager::SetMultiSamplingLevelToFrameBuffer(Render::FrameBuffer* fram
   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetMultiSamplingLevelToFrameBuffer, frameBuffer, multiSamplingLevel);
 }
 
+void UpdateManager::CaptureRenderingResult(Render::FrameBuffer* frameBuffer)
+{
+  using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
+
+  // Reserve some memory inside the render queue
+  uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
+
+  // Construct message in the render queue memory; note that delete should not be called on the return value
+  new(slot) DerivedType(&mImpl->renderManager, &RenderManager::CaptureRenderingResult, frameBuffer);
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 08468e8..2a403b9 100644 (file)
@@ -595,6 +595,12 @@ public:
   void SetMultiSamplingLevelToFrameBuffer(Render::FrameBuffer* frameBuffer, uint8_t multiSamplingLevel);
 
   /**
+   * Request to capture rendered result
+   * @param[in] frameBuffer The FrameBuffer
+   */
+  void CaptureRenderingResult(Render::FrameBuffer* frameBuffer);
+
+  /**
    * This is called when the surface of the scene has been replaced.
    * @param[in] scene The scene.
    */
@@ -1467,6 +1473,17 @@ inline void SetMultiSamplingLevelToFrameBuffer(UpdateManager& manager, Render::F
   new(slot) LocalType(&manager, &UpdateManager::SetMultiSamplingLevelToFrameBuffer, &frameBuffer, multiSamplingLevel);
 }
 
+inline void CaptureRenderingResult(UpdateManager& manager, Render::FrameBuffer& frameBuffer)
+{
+  using LocalType = MessageValue1<UpdateManager, Render::FrameBuffer*>;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = manager.ReserveMessageSlot(sizeof(LocalType));
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new(slot) LocalType(&manager, &UpdateManager::CaptureRenderingResult, &frameBuffer);
+}
+
 inline void SetDepthIndicesMessage(UpdateManager& manager, OwnerPointer<NodeDepths>& nodeDepths)
 {
   using LocalType = MessageValue1<UpdateManager, OwnerPointer<NodeDepths>>;
index 4b45a92..3680a86 100644 (file)
@@ -98,4 +98,14 @@ Texture FrameBuffer::GetColorTexture()
   return Dali::Texture(texturePtr);
 }
 
+uint8_t* FrameBuffer::GetRenderedBuffer()
+{
+  return GetImplementation(*this).GetRenderedBuffer();
+}
+
+void FrameBuffer::CaptureRenderedResult()
+{
+  GetImplementation(*this).CaptureRenderedResult();
+}
+
 } //namespace Dali
index 9954182..71dc5ff 100644 (file)
@@ -185,6 +185,18 @@ public:
    */
   Texture GetColorTexture();
 
+  /**
+   * @brief Retrieve rendered buffer.
+   * @return Buffer pointer of captured image.
+   */
+  uint8_t* GetRenderedBuffer();
+
+  /**
+   * @brief Request to capture rendered result
+   * @note This method request to capture once,
+   */
+  void CaptureRenderedResult();
+
 public:
   /**
    * @brief The constructor.