AC_CONFIG_SUBDIRS(web-engine-chromium)
AC_CONFIG_SUBDIRS(web-engine-lwe)
fi
-AC_CONFIG_SUBDIRS(evas-plugin)
+AC_CONFIG_SUBDIRS(dali-extension)
devincludepath=${includedir}
AC_SUBST(devincludepath)
#
-# Copyright (c) 2015 Samsung Electronics Co., Ltd.
+# Copyright (c) 2019 Samsung Electronics Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# limitations under the License.
#
-# Build the Dali evas plugin
+# Build the Dali extension library
extension_src_dir = ../../../dali-extension
# evas-plugin
include ../../../dali-extension/devel-api/evas-plugin/file.list
include ../../../dali-extension/internal/evas-plugin/file.list
+# capture
+include ../../../dali-extension/devel-api/capture/file.list
+include ../../../dali-extension/internal/capture/file.list
lib_LTLIBRARIES =
# Todo Evas plugin separation
libdali_extension_la_SOURCES = \
- $(evas_plugin_public_src_files) \
- $(evas_plugin_internal_src_files)
+ $(evas_plugin_devel_src_files) \
+ $(evas_plugin_internal_src_files) \
+ $(capture_devel_src_files) \
+ $(capture_internal_src_files)
libdali_extension_la_DEPENDENCIES =
libdali_extension_la_CXXFLAGS = \
$(DLOG_CFLAGS) \
+ $(DALI_CFLAGS) \
+ $(DALI_EXTENSION_CFLAGS) \
$(DALI_ADAPTOR_INTEGRATION_CFLAGS) \
$(ELEMENTARY_CFLAGS) \
$(EVAS_CFLAGS) \
$(WAYLAND_CFLAGS) \
+ $(LIBTBM_CFLAGS) \
+ $(LIBPNG_CFLAGS) \
-DEFL_BETA_API_SUPPORT \
-I../../../ \
-Werror -Wall
libdali_extension_la_LIBADD = \
$(DLOG_LIBS) \
+ $(DALI_LIBS) \
$(DALI_ADAPTOR_INTEGRATION_LIBS) \
$(ELEMENTARY_LIBS) \
$(EVAS_LIBS) \
- $(WAYLAND_LIBS)
+ $(WAYLAND_LIBS) \
+ $(LIBTBM_LIBS) \
+ $(LIBPNG_LIBS)
libdali_extension_la_LDFLAGS = \
-rdynamic
dali_extensiondir = $(devincludepath)/dali-extension
dali_extension_HEADERS = ../../../dali-extension/dali-extension.h
+dali_extension_capturedir = $(devincludepath)/dali-extension/devel-api/capture
+dali_extension_capture_HEADERS = $(capture_devel_header_files)
+
dali_extension_evasplugindir = $(devincludepath)/dali-extension/devel-api/evas-plugin
-dali_extension_evasplugin_HEADERS = $(evas_plugin_public_header_files)
+dali_extension_evasplugin_HEADERS = $(evas_plugin_devel_header_files)
PKG_CHECK_MODULES(EVAS, evas)
PKG_CHECK_MODULES(WAYLAND, [ecore-wl2])
+# For capture
+PKG_CHECK_MODULES(LIBTBM, libtbm)
+PKG_CHECK_MODULES(LIBPNG, libpng)
+
devincludepath=${includedir}
AC_SUBST(devincludepath)
*
*/
+#include <dali-extension/devel-api/capture/capture.h>
#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
#endif // __DALI_EXTENSION_H__
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-extension/devel-api/capture/capture.h>
+#include <dali-extension/internal/capture/capture-impl.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+Capture::Capture()
+{
+}
+
+Capture Capture::New()
+{
+ Internal::CapturePtr internal = Internal::Capture::New();
+
+ return Capture(internal.Get());
+}
+
+Capture Capture::New(Dali::Camera::ProjectionMode mode)
+{
+ Internal::CapturePtr internal = Internal::Capture::New(mode);
+
+ return Capture(internal.Get());
+}
+
+Capture Capture::DownCast(BaseHandle handle)
+{
+ return Capture(dynamic_cast<Internal::Capture*>(handle.GetObjectPtr()));
+}
+
+Capture::~Capture()
+{
+}
+
+Capture::Capture(const Capture& copy)
+: BaseHandle(copy)
+{
+}
+
+Capture& Capture::operator=(const Capture& rhs)
+{
+ BaseHandle::operator=(rhs);
+ return *this;
+}
+
+void Capture::Start(Actor source, const Vector2& size, const std::string &path, const Vector4& clearColor )
+{
+ GetImpl(*this).Start(source, size, path, clearColor);
+}
+
+Capture::FinishState Capture::GetFinishState()
+{
+ return GetImpl(*this).GetFinishState();
+}
+
+Capture::CaptureSignalType& Capture::FinishedSignal()
+{
+ return GetImpl(*this).FinishedSignal();
+}
+
+Capture::Capture(Internal::Capture* internal)
+: BaseHandle(internal)
+{
+}
+
+} // namespace Extension
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_EXTENSION_CAPTURE_H__
+#define __DALI_EXTENSION_CAPTURE_H__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @addtogroup CAPI_DALI_EXTENSION_FRAMEWORK_MODULE
+ * @{
+ */
+
+// EXTERNAL HEADERS
+#include <dali/dali.h>
+
+// INTERNAL HEADERS
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+class Capture;
+}
+
+/**
+ * @brief Capture snapshots the current scene and save as a file.
+ *
+ * Applications should follow the example below to create capture :
+ *
+ * @code
+ * Capture capture = Capture::New();
+ * @endcode
+ *
+ * If required, you can also connect class member function to a signal :
+ *
+ * @code
+ * capture.FinishedSignal().Connect(this, &CaptureSceneExample::OnCaptureFinished);
+ * @endcode
+ *
+ * At the connected class member function, you can know whether capture finish state.
+ *
+ * @code
+ * void CaptureSceneExample::OnCaptureFinished(Capture capture)
+ * {
+ * if (capture.GetFinishState() == Capture::SUCCESSED)
+ * {
+ * // Do something
+ * }
+ * else
+ * {
+ * // Do something
+ * }
+ * }
+ * @endcode
+ */
+class DALI_IMPORT_API Capture : public BaseHandle
+{
+public:
+ enum FinishState
+ {
+ SUCCESSED,
+ FAILED
+ };
+
+ /**
+ * @brief Typedef for signals sent by this class.
+ */
+ typedef Signal< void (Capture) > CaptureSignalType;
+
+ /**
+ * @brief Create an uninitialized Capture; this can be initialized with Actor::New().
+ *
+ * Calling member functions with an uninitialized Dali::Object is not allowed.
+ */
+ Capture();
+
+ /**
+ * @brief Create an initialized Capture.
+ *
+ * @return A handle to a newly allocated Dali resource.
+ */
+ static Capture New();
+
+ /**
+ * @brief Create an initialized Capture.
+ *
+ * @param[in] mode camera projection mode.
+ * @return A handle to a newly allocated Dali resource.
+ */
+ static Capture New(Dali::Camera::ProjectionMode mode);
+
+ /**
+ * @brief Downcast an Object handle to Capture handle.
+ *
+ * If handle points to a Capture object the downcast produces valid
+ * handle. If not the returned handle is left uninitialized.
+ *
+ * @param[in] handle to An object.
+ * @return handle to a Capture object or an uninitialized handle.
+ */
+ static Capture DownCast( BaseHandle handle );
+
+ /**
+ * @brief Dali::Actor is intended as a base class.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~Capture();
+
+ /**
+ * @brief This copy constructor is required for (smart) pointer semantics.
+ *
+ * @param[in] copy A reference to the copied handle.
+ */
+ Capture(const Capture& copy);
+
+ /**
+ * @brief This assignment operator is required for (smart) pointer semantics.
+ *
+ * @param[in] rhs A reference to the copied handle.
+ * @return A reference to this.
+ */
+ Capture& operator=(const Capture& rhs);
+
+ /**
+ * @brief Start capture and save the image as a file.
+ *
+ * @param[in] source source actor to be used for capture.
+ * @param[in] size captured size.
+ * @param[in] path image file path to be saved as a file.
+ * @param[in] clearColor background color of captured scene
+ */
+ void Start(Actor source, const Vector2& size, const std::string &path, const Vector4& clearColor = Dali::Color::TRANSPARENT );
+
+ /**
+ * @brief Retrieve the capture finish status.
+ *
+ * @return Whether success or not.
+ */
+ FinishState GetFinishState();
+
+ /**
+ * @brief Get finished signal.
+ *
+ * @return finished signal instance.
+ */
+ CaptureSignalType& FinishedSignal();
+
+public: // Not intended for application developers
+ /**
+ * @brief This constructor is used by New() methods.
+ *
+ * @param[in] internal A pointer to a newly allocated Dali resource.
+ */
+ explicit DALI_INTERNAL Capture(Internal::Capture* internal);
+};
+
+} // namespace Extension
+
+} // namespace Dali
+
+/**
+ * @}
+ */
+
+#endif // __DALI_EXTENSION_CAPTURE_H__
--- /dev/null
+capture_devel_header_files = \
+ $(extension_src_dir)/devel-api/capture/capture.h
+
+capture_devel_src_files = \
+ $(extension_src_dir)/devel-api/capture/capture.cpp
-evas_plugin_public_header_files = \
+evas_plugin_devel_header_files = \
$(extension_src_dir)/devel-api/evas-plugin/evas-plugin.h
-evas_plugin_public_src_files = \
+evas_plugin_devel_src_files = \
$(extension_src_dir)/devel-api/evas-plugin/evas-plugin.cpp
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+
+#include <dali/integration-api/debug.h>
+#include <dali/integration-api/adaptors/adaptor.h>
+
+#include <fstream>
+#include <string.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/capture/capture-impl.h>
+
+#define ENABLED_CAPTURE_LOGGING
+
+#ifdef ENABLED_CAPTURE_LOGGING
+#define DALI_CAPTURE_STATE(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, "%s:%d " format "\n", __PRETTY_FUNCTION__, __LINE__, ## args)
+#else
+#define DALI_CAPTURE_STATE(format, args...)
+#endif
+
+namespace
+{
+unsigned int TIME_OUT_DURATION = 1000;
+}
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+Capture::Capture()
+: mProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION)
+, mTbmSurface(NULL)
+, mFinishState(Dali::Extension::Capture::FAILED)
+{
+}
+
+Capture::Capture(Dali::Camera::ProjectionMode mode)
+: mProjectionMode(mode)
+, mTbmSurface(NULL)
+, mFinishState(Dali::Extension::Capture::FAILED)
+{
+}
+
+CapturePtr Capture::New()
+{
+ CapturePtr pWorker = new Capture();
+
+ // Second-phase construction
+ pWorker->Initialize();
+
+ return pWorker;
+}
+
+CapturePtr Capture::New(Dali::Camera::ProjectionMode mode)
+{
+ CapturePtr pWorker = new Capture(mode);
+
+ // Second-phase construction
+ pWorker->Initialize();
+
+ return pWorker;
+}
+
+void Capture::Start(Actor source, const Vector2& size, const std::string &path, const Vector4& clearColor)
+{
+ DALI_ASSERT_ALWAYS(path.size() > 4 && "Path is invalid.");
+
+ // Increase the reference count focely to avoid application mistake.
+ Reference();
+
+ mPath = path;
+
+ DALI_CAPTURE_STATE("Start Size[%.2f, %.2f] Path[%s]", size.width, size.height, path.c_str());
+
+ DALI_ASSERT_ALWAYS(source && "Source is NULL.");
+
+ UnsetResources();
+ SetupResources(size, clearColor, source);
+}
+
+Dali::Extension::Capture::FinishState Capture::GetFinishState()
+{
+ return mFinishState;
+}
+
+Dali::Extension::Capture::CaptureSignalType& Capture::FinishedSignal()
+{
+ return mFinishedSignal;
+}
+
+void Capture::Initialize()
+{
+}
+
+Capture::~Capture()
+{
+}
+
+void Capture::CreateSurface(const Vector2& size)
+{
+ DALI_ASSERT_ALWAYS(!mTbmSurface && "mTbmSurface is already created.");
+
+ mTbmSurface = tbm_surface_create(size.width, size.height, TBM_FORMAT_RGBA8888);
+ DALI_CAPTURE_STATE("Create mTbmSurface[%p]", mTbmSurface);
+}
+
+void Capture::DeleteSurface()
+{
+ DALI_ASSERT_ALWAYS(mTbmSurface && "mTbmSurface is empty.");
+
+ DALI_CAPTURE_STATE("Delete mTbmSurface[%p]", mTbmSurface);
+
+ tbm_surface_destroy(mTbmSurface);
+ mTbmSurface = NULL;
+}
+
+void Capture::ClearSurface(const Vector2& size)
+{
+ DALI_ASSERT_ALWAYS(mTbmSurface && "mTbmSurface is empty.");
+
+ tbm_surface_info_s surface_info;
+
+ if( tbm_surface_map( mTbmSurface, TBM_SURF_OPTION_WRITE, &surface_info) == TBM_SURFACE_ERROR_NONE )
+ {
+ //DALI_ASSERT_ALWAYS(surface_info.bpp == 32 && "unsupported tbm format");
+
+ unsigned char* ptr = surface_info.planes[0].ptr;
+ memset( ptr, 0, surface_info.size ); // TODO: support color
+
+ if( tbm_surface_unmap( mTbmSurface ) != TBM_SURFACE_ERROR_NONE )
+ {
+ DALI_CAPTURE_STATE( "Fail to unmap tbm_surface\n" );
+ }
+ }
+ else
+ {
+ DALI_ASSERT_ALWAYS(0 && "tbm_surface_map failed");
+ }
+
+ DALI_CAPTURE_STATE("Clear mTbmSurface[%p]", mTbmSurface);
+}
+
+bool Capture::IsSurfaceCreated()
+{
+ return mTbmSurface != 0;
+}
+
+void Capture::CreateNativeImageSource()
+{
+ Dali::Adaptor& adaptor = Dali::Adaptor::Get();
+
+ DALI_ASSERT_ALWAYS(adaptor.IsAvailable() && "Dali::Adaptor is not available.");
+
+ DALI_ASSERT_ALWAYS(mTbmSurface && "mTbmSurface is empty.");
+
+ DALI_ASSERT_ALWAYS(!mNativeImageSourcePtr && "NativeImageSource is already created.");
+
+ // create the NativeImageSource object with our surface
+ mNativeImageSourcePtr = NativeImageSource::New(Dali::Any(mTbmSurface));
+
+ DALI_CAPTURE_STATE("Create NativeImageSource[0x%X]", mNativeImageSourcePtr.Get());
+}
+
+void Capture::DeleteNativeImageSource()
+{
+ DALI_ASSERT_ALWAYS(mNativeImageSourcePtr && "mNativeImageSource is NULL.");
+
+ DALI_CAPTURE_STATE("Delete NativeImageSource[0x%X]", mNativeImageSourcePtr.Get());
+
+ mNativeImageSourcePtr.Reset();
+}
+
+bool Capture::IsNativeImageSourceCreated()
+{
+ return mNativeImageSourcePtr;
+}
+
+void Capture::CreateFrameBuffer()
+{
+ DALI_ASSERT_ALWAYS(mNativeImageSourcePtr && "NativeImageSource is NULL.");
+
+ DALI_ASSERT_ALWAYS(!mFrameBuffer && "FrameBuffer is already created.");
+
+ mNativeTexture = Texture::New( *mNativeImageSourcePtr );
+
+ // Create a FrameBuffer object with no default attachments.
+ mFrameBuffer = FrameBuffer::New( mNativeTexture.GetWidth(), mNativeTexture.GetHeight(), FrameBuffer::Attachment::NONE );
+ // Add a color attachment to the FrameBuffer object.
+ mFrameBuffer.AttachColorTexture( mNativeTexture );
+
+ DALI_CAPTURE_STATE("Create FrameBuffer");
+}
+
+void Capture::DeleteFrameBuffer()
+{
+ DALI_ASSERT_ALWAYS(mFrameBuffer && "FrameBuffer is NULL.");
+
+ DALI_CAPTURE_STATE("Delete FrameBuffer");
+
+ mFrameBuffer.Reset();
+ mNativeTexture.Reset();
+}
+
+bool Capture::IsFrameBufferCreated()
+{
+ return mFrameBuffer;
+}
+
+void Capture::SetupRenderTask(Actor source, const Vector4& clearColor)
+{
+ DALI_ASSERT_ALWAYS(source && "Source is empty.");
+
+ mSource = source;
+
+ // Check the original parent about source.
+ mParent = mSource.GetParent();
+
+ Stage stage = Stage::GetCurrent();
+ Size stageSize = stage.GetSize();
+
+ // Add to stage for rendering the source. If source isn't on the stage then it never be rendered.
+ stage.Add(mSource);
+
+ DALI_ASSERT_ALWAYS(!mCameraActor && "CameraActor is already created.");
+
+ mCameraActor = CameraActor::New( stageSize );
+ mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
+ mCameraActor.SetAnchorPoint(AnchorPoint::CENTER);
+
+ if(mProjectionMode == Camera::ORTHOGRAPHIC_PROJECTION)
+ {
+ mCameraActor.SetOrthographicProjection(stageSize);
+ }
+ stage.Add(mCameraActor);
+
+ DALI_ASSERT_ALWAYS(mFrameBuffer && "Framebuffer is NULL.");
+
+ DALI_ASSERT_ALWAYS(!mRenderTask && "RenderTask is already created.");
+
+ RenderTaskList taskList = stage.GetRenderTaskList();
+ mRenderTask = taskList.CreateTask();
+ mRenderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
+ mRenderTask.SetSourceActor(source);
+ mRenderTask.SetCameraActor(mCameraActor);
+ mRenderTask.SetScreenToFrameBufferFunction(RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION);
+ mRenderTask.SetFrameBuffer(mFrameBuffer);
+ mRenderTask.SetClearColor( clearColor );
+ mRenderTask.SetClearEnabled( true );
+ mRenderTask.SetProperty( RenderTask::Property::REQUIRES_SYNC, true );
+ mRenderTask.FinishedSignal().Connect(this, &Capture::OnRenderFinished);
+ mRenderTask.GetCameraActor().SetInvertYAxis( true );
+
+ mTimer = Timer::New(TIME_OUT_DURATION);
+ mTimer.TickSignal().Connect(this, &Capture::OnTimeOut);
+ mTimer.Start();
+
+ DALI_CAPTURE_STATE("Setup Camera and RenderTask.");
+}
+
+void Capture::UnsetRenderTask()
+{
+ DALI_ASSERT_ALWAYS(mCameraActor && "CameraActor is NULL.");
+
+ DALI_CAPTURE_STATE("Unset Camera and RenderTask");
+
+ if (mParent)
+ {
+ // Restore the parent of source.
+ mParent.Add(mSource);
+ mParent.Reset();
+ }
+ else
+ {
+ mSource.Unparent();
+ }
+
+ mSource.Reset();
+
+ mTimer.Reset();
+
+ mCameraActor.Unparent();
+ mCameraActor.Reset();
+
+ DALI_ASSERT_ALWAYS(mRenderTask && "RenderTask is NULL.");
+
+ RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
+ RenderTask firstTask = taskList.GetTask( 0u );
+
+ // Stop rendering via frame-buffers as empty handle is used to clear target
+ firstTask.SetFrameBuffer(FrameBuffer());
+
+ taskList.RemoveTask(mRenderTask);
+ mRenderTask.Reset();
+}
+
+bool Capture::IsRenderTaskSetup()
+{
+ return mCameraActor && mRenderTask;
+}
+
+void Capture::SetupResources(const Vector2& size, const Vector4& clearColor, Actor source)
+{
+ CreateSurface(size);
+ ClearSurface(size);
+
+ CreateNativeImageSource();
+
+ CreateFrameBuffer();
+
+ SetupRenderTask(source, clearColor);
+
+ DALI_CAPTURE_STATE("Setup Resources");
+}
+
+void Capture::UnsetResources()
+{
+ if (IsRenderTaskSetup())
+ {
+ UnsetRenderTask();
+ }
+
+ if (IsFrameBufferCreated())
+ {
+ DeleteFrameBuffer();
+ }
+
+ if (IsNativeImageSourceCreated())
+ {
+ DeleteNativeImageSource();
+ }
+
+ if (IsSurfaceCreated())
+ {
+ DeleteSurface();
+ }
+
+ DALI_CAPTURE_STATE("Unset Resources");
+}
+
+void Capture::OnRenderFinished(RenderTask& task)
+{
+ DALI_CAPTURE_STATE("Render finished");
+
+ mFinishState = Dali::Extension::Capture::SUCCESSED;
+
+ mTimer.Stop();
+
+ if (!Save())
+ {
+ mFinishState = Dali::Extension::Capture::FAILED;
+ DALI_LOG_ERROR("Fail to Capture mTbmSurface[%p] Path[%s]", mTbmSurface, mPath.c_str());
+ }
+
+ Dali::Extension::Capture handle(this);
+ mFinishedSignal.Emit(handle);
+
+ UnsetResources();
+
+ // Decrease the reference count forcely. It is increased at Start().
+ Unreference();
+}
+
+bool Capture::OnTimeOut()
+{
+ DALI_CAPTURE_STATE("Timeout");
+
+ mFinishState = Dali::Extension::Capture::FAILED;
+
+ Dali::Extension::Capture handle(this);
+ mFinishedSignal.Emit(handle);
+
+ UnsetResources();
+
+ // Decrease the reference count forcely. It is increased at Start().
+ Unreference();
+
+ return false;
+}
+
+bool Capture::Save()
+{
+ DALI_ASSERT_ALWAYS(mNativeImageSourcePtr && "mNativeImageSourcePtr is NULL");
+
+ return mNativeImageSourcePtr->EncodeToFile(mPath);
+}
+
+} // End of namespace Internal
+
+} // End of namespace Extension
+
+} // End of namespace Dali
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_CAPTURE_H__
+#define __DALI_EXTENSION_INTERNAL_CAPTURE_H__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <string>
+#include <tbm_surface.h>
+
+// INTERNAL INCLUDES
+#include <dali/dali.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali-extension/devel-api/capture/capture.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class Capture;
+typedef IntrusivePtr<Capture> CapturePtr;
+
+class Capture : public BaseObject, public ConnectionTracker
+{
+public:
+ typedef unsigned char Pixel;
+ typedef Pixel* PixelPtr;
+
+public:
+ /**
+ * @brief Constructor.
+ */
+ Capture();
+ Capture(Dali::Camera::ProjectionMode mode);
+
+ /**
+ * @copydoc Dali::Extension::New
+ */
+ static CapturePtr New();
+
+ /**
+ * @copydoc Dali::Extension::New
+ */
+ static CapturePtr New(Dali::Camera::ProjectionMode mode);
+
+ /**
+ * @copydoc Dali::Extension::Start
+ */
+ void Start(Actor source, const Vector2& size, const std::string &path, const Vector4& clearColor);
+
+ /**
+ * @copydoc Dali::Extension::GetFinishState
+ */
+ Dali::Extension::Capture::FinishState GetFinishState();
+
+ /**
+ * @copydoc Dali::Extension::FinishedSignal
+ */
+ Dali::Extension::Capture::CaptureSignalType& FinishedSignal();
+
+protected:
+
+ /**
+ * @brief Second-phase constructor. Must be called immediately after creating a new Capture;
+ */
+ void Initialize(void);
+
+ /**
+ * @brief A reference counted object may only be deleted by calling Unreference()
+ */
+ virtual ~Capture();
+
+private:
+ /**
+ * @brief Create surface.
+ *
+ * @param[in] size of surface.
+ */
+ void CreateSurface(const Vector2& size);
+
+ /**
+ * @brief Delete surface.
+ */
+ void DeleteSurface();
+
+ /**
+ * @brief Clear surface with color.
+ *
+ * @param[in] size of clear aread.
+ */
+ void ClearSurface(const Vector2& size);
+
+ /**
+ * @brief Query whether surface is created or not.
+ *
+ * @return True is surface is created.
+ */
+ bool IsSurfaceCreated();
+
+ /**
+ * @brief Create native image source.
+ */
+ void CreateNativeImageSource();
+
+ /**
+ * @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.
+ */
+ void CreateFrameBuffer();
+
+ /**
+ * @brief Delete frame buffer.
+ */
+ void DeleteFrameBuffer();
+
+ /**
+ * @brief Query whether frame buffer is created or not.
+ *
+ * @return True is frame buffer is created.
+ */
+ bool IsFrameBufferCreated();
+
+ /**
+ * @brief Setup render task.
+ *
+ * @param[in] source is captured.
+ * @param[in] clearColor background color
+ */
+ void SetupRenderTask(Actor source, const Vector4& clearColor);
+
+ /**
+ * @brief Unset render task.
+ */
+ void UnsetRenderTask();
+
+ /**
+ * @brief Query whether render task is setup or not.
+ *
+ * @return True is render task is setup.
+ */
+ bool IsRenderTaskSetup();
+
+ /**
+ * @brief Setup resources for capture.
+ *
+ * @param[in] size is surface size.
+ * @param[in] clearColor is clear color of surface.
+ * @param[in] source is captured.
+ */
+ void SetupResources(const Vector2& size, const Vector4& clearColor, Actor source);
+
+ /**
+ * @brief Unset resources for capture.
+ */
+ void UnsetResources();
+
+ /**
+ * @brief Callback when render is finished.
+ *
+ * @param[in] task is used for capture.
+ */
+ void OnRenderFinished(RenderTask& task);
+
+ /**
+ * @brief Callback when timer is finished.
+ *
+ * @return True is timer start again.
+ */
+ bool OnTimeOut();
+
+ /**
+ * @brief Save framebuffer.
+ *
+ * @return True is success to save, false is fail.
+ */
+ bool Save();
+
+private:
+
+ // Undefined
+ Capture(const Capture&);
+
+ // Undefined
+ Capture& operator=(const Capture& rhs);
+
+private:
+ Texture mNativeTexture;
+ FrameBuffer mFrameBuffer;
+ RenderTask mRenderTask;
+ Actor mParent;
+ Actor mSource;
+ CameraActor mCameraActor;
+ Camera::ProjectionMode mProjectionMode;
+ Timer mTimer; ///< For timeout.
+ Dali::Extension::Capture::CaptureSignalType mFinishedSignal;
+ std::string mPath;
+ NativeImageSourcePtr mNativeImageSourcePtr; ///< pointer to surface image
+ tbm_surface_h mTbmSurface;
+ Dali::Extension::Capture::FinishState mFinishState;
+};
+
+} // End of namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::Capture& GetImpl(Extension::Capture& captureWorker)
+{
+ DALI_ASSERT_ALWAYS(captureWorker && "Capture handle is empty");
+
+ BaseObject& handle = captureWorker.GetBaseObject();
+
+ return static_cast<Internal::Capture&>(handle);
+}
+
+inline const Internal::Capture& GetImpl(const Extension::Capture& captureWorker)
+{
+ DALI_ASSERT_ALWAYS(captureWorker && "Capture handle is empty");
+
+ const BaseObject& handle = captureWorker.GetBaseObject();
+
+ return static_cast<const Internal::Capture&>(handle);
+}
+
+} // End of namespace Extension
+
+} // End of namespace Dali
+
+#endif // __DALI_EXTENSION_INTERNAL_CAPTURE_H__
--- /dev/null
+capture_internal_header_files = \
+ $(extension_src_dir)/internal/capture/capture-impl.h
+
+capture_internal_src_files = \
+ $(extension_src_dir)/internal/capture/capture-impl.cpp
BuildRequires: pkgconfig(dali-toolkit)
BuildRequires: pkgconfig(dlog)
+# For capture
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(libpng)
+
# For evas-plugin
BuildRequires: pkgconfig(dali-adaptor-integration)
BuildRequires: pkgconfig(elementary)