From: seungho Date: Tue, 23 Mar 2021 12:16:46 +0000 (+0900) Subject: [Tizen] Make possible to capture on the old driver devices. X-Git-Tag: accepted/tizen/6.0/unified/20210324.210349^0 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=6fb1af0bab60da8df4bd9a2f7adc273e3ec11722 [Tizen] Make possible to capture on the old driver devices. Change-Id: I5d20b4c70b6da1e98b0c29d465a8a700c2a0410a Signed-off-by: seungho --- diff --git a/dali/internal/event/rendering/frame-buffer-impl.cpp b/dali/internal/event/rendering/frame-buffer-impl.cpp index 606537e..e1c1ab1 100644 --- a/dali/internal/event/rendering/frame-buffer-impl.cpp +++ b/dali/internal/event/rendering/frame-buffer-impl.cpp @@ -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; diff --git a/dali/internal/event/rendering/frame-buffer-impl.h b/dali/internal/event/rendering/frame-buffer-impl.h index 1b59e74..74ccf87 100644 --- a/dali/internal/event/rendering/frame-buffer-impl.h +++ b/dali/internal/event/rendering/frame-buffer-impl.h @@ -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 diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index e833923..2e4ad8f 100755 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -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); } } diff --git a/dali/internal/render/common/render-manager.h b/dali/internal/render/common/render-manager.h index 2e3ea2d..de9f61b 100644 --- a/dali/internal/render/common/render-manager.h +++ b/dali/internal/render/common/render-manager.h @@ -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 */ diff --git a/dali/internal/render/renderers/render-frame-buffer.cpp b/dali/internal/render/renderers/render-frame-buffer.cpp index 8210648..e003a82 100644 --- a/dali/internal/render/renderers/render-frame-buffer.cpp +++ b/dali/internal/render/renderers/render-frame-buffer.cpp @@ -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 diff --git a/dali/internal/render/renderers/render-frame-buffer.h b/dali/internal/render/renderers/render-frame-buffer.h index 5dbbc32..0fcbd3b 100644 --- a/dali/internal/render/renderers/render-frame-buffer.h +++ b/dali/internal/render/renderers/render-frame-buffer.h @@ -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 diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 58fb0bc..5fe5c44 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -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; + + // 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 diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 73e0f38..0417ff3 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -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; + + // 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 >; diff --git a/dali/public-api/rendering/frame-buffer.cpp b/dali/public-api/rendering/frame-buffer.cpp index 4b45a92..3680a86 100644 --- a/dali/public-api/rendering/frame-buffer.cpp +++ b/dali/public-api/rendering/frame-buffer.cpp @@ -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 diff --git a/dali/public-api/rendering/frame-buffer.h b/dali/public-api/rendering/frame-buffer.h index 9954182..71dc5ff 100644 --- a/dali/public-api/rendering/frame-buffer.h +++ b/dali/public-api/rendering/frame-buffer.h @@ -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.