[Tizen] Make possible to capture on the old driver devices. 76/255776/5 accepted/tizen/6.0/unified/20210324.210349 submit/tizen_6.0/20210324.154322
authorseungho <sbsh.baek@samsung.com>
Tue, 23 Mar 2021 12:16:46 +0000 (21:16 +0900)
committerseungho <sbsh.baek@samsung.com>
Wed, 24 Mar 2021 06:05:43 +0000 (15:05 +0900)
Change-Id: I5d20b4c70b6da1e98b0c29d465a8a700c2a0410a
Signed-off-by: seungho <sbsh.baek@samsung.com>
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 606537e..e1c1ab1 100644 (file)
@@ -123,6 +123,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 1b59e74..74ccf87 100644 (file)
@@ -100,6 +100,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 e833923..2e4ad8f 100755 (executable)
@@ -386,6 +386,11 @@ void RenderManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer*
   frameBuffer->AttachDepthStencilTexture( mImpl->context, texture, mipmapLevel );
 }
 
+void RenderManager::CaptureRenderingResult(Render::FrameBuffer* frameBuffer)
+{
+  frameBuffer->CaptureRenderingResult();
+}
+
 void RenderManager::AddVertexBuffer( OwnerPointer< Render::VertexBuffer >& vertexBuffer )
 {
   mImpl->vertexBufferContainer.PushBack( vertexBuffer.Release() );
@@ -1088,6 +1093,7 @@ void RenderManager::RenderScene( Integration::RenderStatus& status, Integration:
     if ( renderToFbo )
     {
       mImpl->currentContext->Flush();
+      instruction.mFrameBuffer->DrawRenderedBuffer(*mImpl->currentContext);
     }
   }
 
index 2e3ea2d..de9f61b 100644 (file)
@@ -309,6 +309,12 @@ public:
   void AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel );
 
   /**
+   * 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 8210648..e003a82 100644 (file)
@@ -48,11 +48,19 @@ FrameBuffer::FrameBuffer( uint32_t width, uint32_t height, Mask attachments )
   mStencilBuffer( attachments & Dali::FrameBuffer::Attachment::STENCIL ),
   mWidth( width ),
   mHeight( height ),
-  mColorAttachmentCount( 0u )
+  mColorAttachmentCount( 0u ),
+  mCaptureRenderedResult(false),
+  mCaptured(false)
 {
 }
 
-FrameBuffer::~FrameBuffer() = default;
+FrameBuffer::~FrameBuffer()
+{
+  if(mCaptured)
+  {
+    delete[] mRenderedBuffer;
+  }
+}
 
 void FrameBuffer::Destroy( Context& context )
 {
@@ -159,6 +167,43 @@ uint32_t FrameBuffer::GetHeight() const
   return mHeight;
 }
 
+void FrameBuffer::DrawRenderedBuffer(Context& context)
+{
+  if(!mCaptureRenderedResult)
+  {
+    return;
+  }
+
+  if(mCaptured)
+  {
+    delete[] mRenderedBuffer;
+  }
+
+  context.BindFramebuffer(GL_FRAMEBUFFER, mId);
+  mRenderedBuffer = new GLubyte[mWidth * mHeight * sizeof(GL_UNSIGNED_BYTE)];
+  context.ReadPixels(0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, mRenderedBuffer);
+  context.BindFramebuffer(GL_FRAMEBUFFER, 0);
+  mCaptureRenderedResult = false;
+  mCaptured = true;
+}
+
+GLubyte* FrameBuffer::GetRenderedBuffer()
+{
+  if(mCaptured)
+  {
+    return mRenderedBuffer;
+  }
+  else
+  {
+    return nullptr;
+  }
+}
+
+void FrameBuffer::CaptureRenderingResult()
+{
+  mCaptureRenderedResult = true;
+}
+
 
 } //Render
 
index 5dbbc32..0fcbd3b 100644 (file)
@@ -121,6 +121,22 @@ public:
    */
   GLuint GetTextureId(uint8_t index) { return mTextureId[index]; };
 
+  /**
+   * @brief Read render result
+   */
+  void DrawRenderedBuffer(Context& context);
+
+  /**
+   * @brief Retrieve rendered buffer.
+   * @return Buffer pointer
+   */
+  GLubyte* GetRenderedBuffer();
+
+  /**
+   * @brief Request to Read rendered result.
+   */
+  void CaptureRenderingResult();
+
 private:
 
   /**
@@ -142,6 +158,9 @@ private:
   uint32_t mWidth;
   uint32_t mHeight;
   uint8_t mColorAttachmentCount;
+  GLubyte* mRenderedBuffer;
+  bool     mCaptureRenderedResult;
+  bool     mCaptured;
 };
 
 } // namespace Render
index 58fb0bc..5fe5c44 100644 (file)
@@ -1449,6 +1449,17 @@ void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer*
   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
 }
 
+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 73e0f38..0417ff3 100644 (file)
@@ -605,6 +605,12 @@ public:
   void AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel );
 
   /**
+   * 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 AttachDepthStencilTextureToFrameBuffer( UpdateManager& manager, Rend
   new (slot) LocalType( &manager, &UpdateManager::AttachDepthStencilTextureToFrameBuffer, &frameBuffer, texture, mipmapLevel );
 }
 
+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.