#include <fstream>
// INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/bitmap-saver.h>
#include <dali/devel-api/adaptor-framework/native-image-source-devel.h>
#include <dali/devel-api/adaptor-framework/window-devel.h>
#include <dali/integration-api/adaptor-framework/adaptor.h>
-
-namespace
-{
-unsigned int TIME_OUT_DURATION = 1000;
-}
+#include <dali/internal/adaptor/common/adaptor-impl.h>
+#include <dali/internal/graphics/gles/egl-graphics.h>
namespace Dali
{
{
namespace Adaptor
{
+namespace
+{
+constexpr int32_t GL_VERSION_NATIVE_IMAGE_SOURCE_AVAILABLE = 30;
+constexpr uint32_t TIME_OUT_DURATION = 1000;
+} // namespace
+
Capture::Capture()
: mQuality(DEFAULT_QUALITY),
mTimer(),
Capture::~Capture()
{
DeleteNativeImageSource();
+ mTexture.Reset();
}
CapturePtr Capture::New()
void Capture::Start(Dali::Actor source, const Dali::Vector2& position, const Dali::Vector2& size, const std::string& path, const Dali::Vector4& clearColor)
{
+ if(!source)
+ {
+ return;
+ }
+
// Increase the reference count focely to avoid application mistake.
Reference();
mFileSave = true;
}
- DALI_ASSERT_ALWAYS(source && "Source is NULL.");
-
UnsetResources();
SetupResources(position, size, clearColor, source);
}
return mNativeImageSourcePtr;
}
-Dali::Capture::CaptureFinishedSignalType& Capture::FinishedSignal()
+Dali::Devel::PixelBuffer Capture::GetCapturedBuffer()
{
- return mFinishedSignal;
+ if(!mPixelBuffer || (mPixelBuffer && !mPixelBuffer.GetBuffer()))
+ {
+ std::vector<uint8_t> buffer;
+ uint32_t width, height;
+ Dali::Pixel::Format pixelFormat;
+ if(!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));
+ }
+ return mPixelBuffer;
}
-void Capture::CreateNativeImageSource(const Vector2& size)
+Dali::Capture::CaptureFinishedSignalType& Capture::FinishedSignal()
{
- Dali::Adaptor& adaptor = Dali::Adaptor::Get();
-
- DALI_ASSERT_ALWAYS(adaptor.IsAvailable() && "Dali::Adaptor is not available.");
-
- DALI_ASSERT_ALWAYS(!mNativeImageSourcePtr && "NativeImageSource is already created.");
-
- // create the NativeImageSource object with our surface
- mNativeImageSourcePtr = Dali::NativeImageSource::New(size.width, size.height, Dali::NativeImageSource::COLOR_DEPTH_DEFAULT);
+ return mFinishedSignal;
}
-void Capture::DeleteNativeImageSource()
+void Capture::CreateTexture(const Vector2& size)
{
- mNativeImageSourcePtr.Reset();
+ if(!mNativeImageSourcePtr)
+ {
+ mNativeImageSourcePtr = Dali::NativeImageSource::New(size.width, size.height, Dali::NativeImageSource::COLOR_DEPTH_DEFAULT);
+ mTexture = Dali::Texture::New(*mNativeImageSourcePtr);
+ }
}
-bool Capture::IsNativeImageSourceCreated()
+void Capture::DeleteNativeImageSource()
{
- return mNativeImageSourcePtr;
+ if(mNativeImageSourcePtr)
+ {
+ mNativeImageSourcePtr.Reset();
+ }
}
void Capture::CreateFrameBuffer()
{
- DALI_ASSERT_ALWAYS(mNativeImageSourcePtr && "NativeImageSource is NULL.");
-
- DALI_ASSERT_ALWAYS(!mFrameBuffer && "FrameBuffer is already created.");
-
- mNativeTexture = Dali::Texture::New(*mNativeImageSourcePtr);
-
- // Create a FrameBuffer object with depth attachments.
- mFrameBuffer = Dali::FrameBuffer::New(mNativeTexture.GetWidth(), mNativeTexture.GetHeight(), Dali::FrameBuffer::Attachment::DEPTH);
- // Add a color attachment to the FrameBuffer object.
- mFrameBuffer.AttachColorTexture(mNativeTexture);
+ if(!mFrameBuffer)
+ {
+ // Create a FrameBuffer object with depth attachments.
+ mFrameBuffer = Dali::FrameBuffer::New(mTexture.GetWidth(), mTexture.GetHeight(), Dali::FrameBuffer::Attachment::DEPTH);
+ // Add a color attachment to the FrameBuffer object.
+ mFrameBuffer.AttachColorTexture(mTexture);
+ }
}
void Capture::DeleteFrameBuffer()
{
- DALI_ASSERT_ALWAYS(mFrameBuffer && "FrameBuffer is NULL.");
-
- mFrameBuffer.Reset();
- mNativeTexture.Reset();
+ if(mFrameBuffer)
+ {
+ mFrameBuffer.Reset();
+ }
}
bool Capture::IsFrameBufferCreated()
void Capture::SetupRenderTask(const Dali::Vector2& position, const Dali::Vector2& size, Dali::Actor source, const Dali::Vector4& clearColor)
{
- DALI_ASSERT_ALWAYS(source && "Source is empty.");
+ if(!source)
+ {
+ DALI_LOG_ERROR("Source is empty\n");
+ return;
+ }
Dali::Window window = DevelWindow::Get(source);
if(!window)
{
- DALI_LOG_ERROR("The source is not added on the window\n");
+ DALI_LOG_ERROR("The source is not added on the scene\n");
return;
}
window.Add(mCameraActor);
- DALI_ASSERT_ALWAYS(mFrameBuffer && "Framebuffer is NULL.");
-
- DALI_ASSERT_ALWAYS(!mRenderTask && "RenderTask is already created.");
+ if(!mFrameBuffer)
+ {
+ DALI_LOG_ERROR("Frame buffer is not created.\n");
+ return;
+ }
Dali::RenderTaskList taskList = window.GetRenderTaskList();
mRenderTask = taskList.CreateTask();
void Capture::UnsetRenderTask()
{
- DALI_ASSERT_ALWAYS(mCameraActor && "CameraActor is NULL.");
-
mTimer.Reset();
- mCameraActor.Unparent();
- mCameraActor.Reset();
-
- DALI_ASSERT_ALWAYS(mRenderTask && "RenderTask is NULL.");
+ if(mCameraActor)
+ {
+ mCameraActor.Unparent();
+ mCameraActor.Reset();
+ }
- Dali::Window window = DevelWindow::Get(mSource);
- Dali::RenderTaskList taskList = window.GetRenderTaskList();
- taskList.RemoveTask(mRenderTask);
- mRenderTask.Reset();
+ if(mRenderTask)
+ {
+ Dali::Window window = DevelWindow::Get(mSource);
+ Dali::RenderTaskList taskList = window.GetRenderTaskList();
+ taskList.RemoveTask(mRenderTask);
+ mRenderTask.Reset();
+ }
mSource.Reset();
}
void Capture::SetupResources(const Dali::Vector2& position, const Dali::Vector2& size, const Dali::Vector4& clearColor, Dali::Actor source)
{
- CreateNativeImageSource(size);
+ CreateTexture(size);
CreateFrameBuffer();
{
if(!SaveFile())
{
+ DALI_LOG_ERROR("Fail to Capture Path[%s]\n", mPath.c_str());
state = Dali::Capture::FinishState::FAILED;
- DALI_LOG_ERROR("Fail to Capture Path[%s]", mPath.c_str());
}
}
bool Capture::SaveFile()
{
- DALI_ASSERT_ALWAYS(mNativeImageSourcePtr && "mNativeImageSourcePtr is NULL");
-
- return Dali::DevelNativeImageSource::EncodeToFile(*mNativeImageSourcePtr, mPath, mQuality);
+ if(mNativeImageSourcePtr)
+ {
+ return Dali::DevelNativeImageSource::EncodeToFile(*mNativeImageSourcePtr, mPath, mQuality);
+ }
+ return false;
}
} // End of namespace Adaptor
#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/capture/capture.h>
#include <dali/public-api/dali-adaptor-common.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
namespace Dali
{
*/
Dali::NativeImageSourcePtr GetNativeImageSource() const;
+ /**
+ * @copydoc Dali::Capture::GetCapturedBuffer
+ */
+ Dali::Devel::PixelBuffer GetCapturedBuffer();
+
/**
* @copydoc Dali::Capture::FinishedSignal
*/
private:
/**
- * @brief Create native image source.
+ * @brief Create texture.
*/
- void CreateNativeImageSource(const Dali::Vector2& size);
+ void CreateTexture(const Dali::Vector2& size);
/**
* @brief Delete native image source.
*/
void DeleteNativeImageSource();
- /**
- * @brief Query whether native image source is created or not.
- *
- * @return True is native image source is created.
- */
- bool IsNativeImageSourceCreated();
-
/**
* @brief Create frame buffer.
*/
private:
uint32_t mQuality;
- Dali::Texture mNativeTexture;
+ Dali::Texture mTexture;
Dali::FrameBuffer mFrameBuffer;
Dali::RenderTask mRenderTask;
Dali::Actor mSource;
Dali::Capture::CaptureFinishedSignalType mFinishedSignal;
std::string mPath;
Dali::NativeImageSourcePtr mNativeImageSourcePtr; ///< pointer to surface image
+ Dali::Devel::PixelBuffer mPixelBuffer;
bool mFileSave;
};