return graphicsProgram->GetParameter(parameterId, outData);
}
+void TestGraphicsController::CaptureRenderingResult(Graphics::Framebuffer& framebuffer, CallbackBase* capturedCallback, uint8_t* capturedBuffer)
+{
+ mCallStack.PushCall("CaptureRenderingResult", "");
+}
+
} // namespace Dali
*/
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)
{
*/
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
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;
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
frameBuffer->SetMultiSamplingLevel(multiSamplingLevel);
}
+void RenderManager::CaptureRenderingResult(Render::FrameBuffer* frameBuffer)
+{
+ frameBuffer->CaptureRenderingResult();
+}
+
void RenderManager::AddVertexBuffer(OwnerPointer<Render::VertexBuffer>& vertexBuffer)
{
mImpl->vertexBufferContainer.PushBack(vertexBuffer.Release());
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
*/
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)
{
}
}
-FrameBuffer::~FrameBuffer() = default;
+FrameBuffer::~FrameBuffer()
+{
+ if(mRenderedBuffer != nullptr)
+ {
+ delete[] mRenderedBuffer;
+ }
+}
void FrameBuffer::Destroy()
{
{
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
}
}
+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
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.
uint32_t mWidth;
uint32_t mHeight;
+ std::unique_ptr<CallbackBase> mCaptureRenderedCallback;
+
+ uint8_t* mRenderedBuffer;
+ bool mCaptureRenderedResult;
+ bool mCaptured;
+
bool mDepthBuffer;
bool mStencilBuffer;
};
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
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.
*/
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>>;
return Dali::Texture(texturePtr);
}
+uint8_t* FrameBuffer::GetRenderedBuffer()
+{
+ return GetImplementation(*this).GetRenderedBuffer();
+}
+
+void FrameBuffer::CaptureRenderedResult()
+{
+ GetImplementation(*this).CaptureRenderedResult();
+}
+
} //namespace Dali
*/
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.