From fef5a4aa14a9db372a5eb050b39a1010207857ac Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Fri, 16 Feb 2024 16:41:20 +0900 Subject: [PATCH] [Tizen] Support to get raw pixel informations of framebuffer for old driver device Let we use Framebuffer capture feature when we use Capture API. It will be used if gles version is low, so let we allow to FBO use targe as native image not working devices. Change-Id: Ica70aff76f5469c7683b486e66d7e85bce313842 Signed-off-by: Eunki, Hong --- .../graphics/gles-impl/egl-graphics-controller.cpp | 5 +++ .../graphics/gles-impl/egl-graphics-controller.h | 4 +++ dali/internal/graphics/gles-impl/gles-context.cpp | 5 +++ .../gles-impl/gles-graphics-framebuffer.cpp | 28 +++++++++++++++ .../graphics/gles-impl/gles-graphics-framebuffer.h | 13 +++++++ dali/internal/system/common/capture-impl.cpp | 41 ++++++++++++++++++---- 6 files changed, 89 insertions(+), 7 deletions(-) diff --git a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp index be7a0c3..1f8979f 100644 --- a/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp +++ b/dali/internal/graphics/gles-impl/egl-graphics-controller.cpp @@ -885,4 +885,9 @@ GLES::PipelineCache& EglGraphicsController::GetPipelineCache() const return *mPipelineCache; } +void EglGraphicsController::CaptureRenderingResult(Graphics::Framebuffer& framebuffer, CallbackBase* capturedCallback, uint8_t* capturedBuffer) +{ + static_cast(&framebuffer)->CaptureRenderingResult(capturedCallback, capturedBuffer); +} + } // namespace Dali::Graphics diff --git a/dali/internal/graphics/gles-impl/egl-graphics-controller.h b/dali/internal/graphics/gles-impl/egl-graphics-controller.h index b89fa31..956fd2a 100644 --- a/dali/internal/graphics/gles-impl/egl-graphics-controller.h +++ b/dali/internal/graphics/gles-impl/egl-graphics-controller.h @@ -313,6 +313,10 @@ public: return {}; } +public: // Framebuffer Capture + void CaptureRenderingResult(Graphics::Framebuffer& framebuffer, CallbackBase* capturedCallback, uint8_t* capturedBuffer) override; + +public: [[nodiscard]] Integration::GlAbstraction* GetGL() const { if(mIsShuttingDown) diff --git a/dali/internal/graphics/gles-impl/gles-context.cpp b/dali/internal/graphics/gles-impl/gles-context.cpp index addd1ad..e38c3cd 100644 --- a/dali/internal/graphics/gles-impl/gles-context.cpp +++ b/dali/internal/graphics/gles-impl/gles-context.cpp @@ -765,6 +765,11 @@ void Context::EndRenderPass(GLES::TextureDependencyChecker& dependencyChecker) auto& gl = *mImpl->mController.GetGL(); gl.Flush(); + if(framebuffer->CaptureRequested()) + { + framebuffer->DrawRenderedBuffer(); + } + /* @todo Full dependency checking would need to store textures in Begin, and create * fence objects here; but we're going to draw all fbos on shared context in serial, * so no real need (yet). Might want to consider ensuring order of render passes, diff --git a/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp b/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp index 6695fbf..b811c2b 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp +++ b/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp @@ -202,6 +202,10 @@ void Framebuffer::DestroyResource() void Framebuffer::DiscardResource() { mController.DiscardResource(this); + + mCaptureRenderedResult = false; + mCapturedBuffer = nullptr; + mCapturedCallback = nullptr; } void Framebuffer::Bind() const @@ -248,4 +252,28 @@ uint32_t Framebuffer::GetGlStencilBufferId() const return mStencilBufferId; } +void Framebuffer::CaptureRenderingResult(CallbackBase* capturedCallback, uint8_t* capturedBuffer) +{ + // Let we make to capture the result. + mCaptureRenderedResult = true; + + mCapturedCallback = capturedCallback; + mCapturedBuffer = capturedBuffer; +} + +void Framebuffer::DrawRenderedBuffer() +{ + auto gl = mController.GetGL(); + if(gl && mCaptureRenderedResult && mCapturedCallback && mCapturedBuffer != nullptr) + { + gl->ReadPixels(0, 0, mCreateInfo.size.width, mCreateInfo.size.height, GL_RGBA, GL_UNSIGNED_BYTE, mCapturedBuffer); + + CallbackBase::Execute(*mCapturedCallback, mCapturedBuffer); + + mCaptureRenderedResult = false; + mCapturedBuffer = nullptr; + mCapturedCallback = nullptr; + } +} + } //namespace Dali::Graphics::GLES diff --git a/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h b/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h index 430b395..18e31f9 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h +++ b/dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h @@ -72,6 +72,15 @@ public: [[nodiscard]] uint32_t GetGlStencilBufferId() const; + void CaptureRenderingResult(CallbackBase* capturedCallback, uint8_t* capturedBuffer); + + void DrawRenderedBuffer(); + + bool CaptureRequested() const + { + return mCaptureRenderedResult; + } + private: /** * Attach a texture to the specified attachment point @@ -88,6 +97,10 @@ private: uint32_t mStencilBufferId{0u}; uint32_t mMultisamples{1u}; bool mInitialized{false}; + + uint8_t* mCapturedBuffer{nullptr}; ///< not owned + Dali::CallbackBase* mCapturedCallback{nullptr}; ///< not owned + bool mCaptureRenderedResult{false}; }; } // namespace Dali::Graphics::GLES diff --git a/dali/internal/system/common/capture-impl.cpp b/dali/internal/system/common/capture-impl.cpp index 7cf2aec..56ef77f 100644 --- a/dali/internal/system/common/capture-impl.cpp +++ b/dali/internal/system/common/capture-impl.cpp @@ -135,15 +135,37 @@ Dali::Devel::PixelBuffer Capture::GetCapturedBuffer() { if(!mPixelBuffer || (mPixelBuffer && !mPixelBuffer.GetBuffer())) { - std::vector buffer; uint32_t width, height; Dali::Pixel::Format pixelFormat; - if(!mNativeImageSourcePtr->GetPixels(buffer, width, height, pixelFormat)) + if(mIsNativeImageSourcePossible) { - return Dali::Devel::PixelBuffer(); + std::vector buffer; + if(!mNativeImageSourcePtr || !mNativeImageSourcePtr->GetPixels(buffer, width, height, pixelFormat)) + { + return Dali::Devel::PixelBuffer(); + } + mPixelBuffer = Dali::Devel::PixelBuffer::New(width, height, pixelFormat); + memcpy(mPixelBuffer.GetBuffer(), &buffer[0], width * height * Dali::Pixel::GetBytesPerPixel(pixelFormat)); + } + else + { + if(!mFrameBuffer || !mTexture) + { + DALI_LOG_ERROR("Capture is not started yet."); + return Dali::Devel::PixelBuffer(); + } + uint8_t* buffer = mFrameBuffer.GetRenderedBuffer(); + if(buffer == nullptr) + { + DALI_LOG_ERROR("Capture is not finished."); + return Dali::Devel::PixelBuffer(); + } + width = mTexture.GetWidth(); + height = mTexture.GetHeight(); + pixelFormat = mTexture.GetPixelFormat(); + mPixelBuffer = Dali::Devel::PixelBuffer::New(width, height, pixelFormat); + memcpy(mPixelBuffer.GetBuffer(), buffer, width * height * Dali::Pixel::GetBytesPerPixel(pixelFormat)); } - mPixelBuffer = Dali::Devel::PixelBuffer::New(width, height, pixelFormat); - memcpy(mPixelBuffer.GetBuffer(), &buffer[0], width * height * Dali::Pixel::GetBytesPerPixel(pixelFormat)); } return mPixelBuffer; } @@ -165,7 +187,7 @@ void Capture::CreateTexture(const Vector2& size) } else { - mTexture = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, unsigned(size.width), unsigned(size.height)); + mTexture = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, unsigned(size.width), unsigned(size.height)); } } @@ -260,6 +282,10 @@ void Capture::SetupRenderTask(const Dali::Vector2& position, const Dali::Vector2 mRenderTask.SetProperty(Dali::RenderTask::Property::REQUIRES_SYNC, true); mRenderTask.FinishedSignal().Connect(this, &Capture::OnRenderFinished); mRenderTask.GetCameraActor().SetInvertYAxis(true); + if(!mIsNativeImageSourcePossible) + { + mFrameBuffer.CaptureRenderedResult(); + } mTimer = Dali::Timer::New(TIME_OUT_DURATION); mTimer.TickSignal().Connect(this, &Capture::OnTimeOut); @@ -378,7 +404,8 @@ bool Capture::SaveFile() } else { - DALI_LOG_ERROR("can't use Capture::SavceFile(). we don't support this function in gles 2.0 \n"); + uint8_t* buffer = mFrameBuffer.GetRenderedBuffer(); + return Dali::EncodeToFile(buffer, mPath, Dali::Pixel::RGBA8888, mTexture.GetWidth(), mTexture.GetHeight(), mQuality); } return false; -- 2.7.4