From: taeyoon0.lee Date: Tue, 5 Dec 2017 08:40:16 +0000 (+0900) Subject: [4.0] Added capture for wearable X-Git-Tag: accepted/tizen/4.0/unified/20171221.070843~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c4fa2120851729ba9515196cec6177de3478d507;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git [4.0] Added capture for wearable Change-Id: I6a6234f56ecb02a0b90b6f670451a1f8322a83cf --- diff --git a/adaptors/tizen/capture-impl-tizen.cpp b/adaptors/tizen/capture-impl-tizen.cpp new file mode 100755 index 0000000..8384bee --- /dev/null +++ b/adaptors/tizen/capture-impl-tizen.cpp @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2014 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 + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include + +namespace +{ +unsigned int TIME_OUT_DURATION = 1000; +} + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ + +Capture::Capture() +: mTimer(), + mPath(), + mNativeImageSourcePtr( NULL ), + mTbmSurface( NULL ) +{ +} + +Capture::Capture( Dali::CameraActor cameraActor ) +: mCameraActor( cameraActor ), + mTimer(), + mPath(), + mNativeImageSourcePtr( NULL ), + mTbmSurface( NULL ) +{ +} + +Capture::~Capture() +{ +} + +CapturePtr Capture::New() +{ + CapturePtr pWorker = new Capture(); + + // Second-phase construction + pWorker->Initialize(); + + return pWorker; +} + +CapturePtr Capture::New( Dali::CameraActor cameraActor ) +{ + CapturePtr pWorker = new Capture( cameraActor ); + + // Second-phase construction + pWorker->Initialize(); + + return pWorker; +} + +void Capture::Start( Dali::Actor source, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor ) +{ + DALI_ASSERT_ALWAYS(path.size() > 4 && "Path is invalid."); + + // Increase the reference count focely to avoid application mistake. + Reference(); + + mPath = path; + + DALI_ASSERT_ALWAYS(source && "Source is NULL."); + + UnsetResources(); + SetupResources( size, clearColor, source ); +} + +Dali::Capture::CaptureFinishedSignalType& Capture::FinishedSignal() +{ + return mFinishedSignal; +} + +void Capture::Initialize() +{ +} + +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 ); +} + +void Capture::DeleteSurface() +{ + DALI_ASSERT_ALWAYS(mTbmSurface && "mTbmSurface is empty."); + + 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_LOG_ERROR( "Fail to unmap tbm_surface\n" ); + } + } + else + { + DALI_ASSERT_ALWAYS(0 && "tbm_surface_map failed"); + } +} + +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 = Dali::NativeImageSource::New( mTbmSurface ); +} + +void Capture::DeleteNativeImageSource() +{ + DALI_ASSERT_ALWAYS(mNativeImageSourcePtr && "mNativeImageSource is NULL."); + + 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 = Dali::Texture::New( *mNativeImageSourcePtr ); + + // Create a FrameBuffer object with no default attachments. + mFrameBuffer = Dali::FrameBuffer::New( mNativeTexture.GetWidth(), mNativeTexture.GetHeight(), Dali::FrameBuffer::Attachment::NONE ); + // Add a color attachment to the FrameBuffer object. + mFrameBuffer.AttachColorTexture( mNativeTexture ); +} + +void Capture::DeleteFrameBuffer() +{ + DALI_ASSERT_ALWAYS(mFrameBuffer && "FrameBuffer is NULL."); + + mFrameBuffer.Reset(); + mNativeTexture.Reset(); +} + +bool Capture::IsFrameBufferCreated() +{ + return mFrameBuffer; +} + +void Capture::SetupRenderTask( Dali::Actor source, const Dali::Vector4& clearColor ) +{ + DALI_ASSERT_ALWAYS(source && "Source is empty."); + + mSource = source; + + // Check the original parent about source. + mParent = mSource.GetParent(); + + Dali::Stage stage = Dali::Stage::GetCurrent(); + Dali::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 ); + + if( !mCameraActor ) + { + mCameraActor = Dali::CameraActor::New( stageSize ); + mCameraActor.SetParentOrigin( ParentOrigin::CENTER ); + mCameraActor.SetAnchorPoint( AnchorPoint::CENTER ); + } + + stage.Add( mCameraActor ); + + DALI_ASSERT_ALWAYS(mFrameBuffer && "Framebuffer is NULL."); + + DALI_ASSERT_ALWAYS(!mRenderTask && "RenderTask is already created."); + + Dali::RenderTaskList taskList = stage.GetRenderTaskList(); + mRenderTask = taskList.CreateTask(); + mRenderTask.SetRefreshRate( Dali::RenderTask::REFRESH_ONCE ); + mRenderTask.SetSourceActor( source ); + mRenderTask.SetCameraActor( mCameraActor ); + mRenderTask.SetScreenToFrameBufferFunction( Dali::RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION ); + mRenderTask.SetFrameBuffer( mFrameBuffer ); + mRenderTask.SetClearColor( clearColor ); + mRenderTask.SetClearEnabled( true ); + mRenderTask.SetProperty( Dali::RenderTask::Property::REQUIRES_SYNC, true ); + mRenderTask.FinishedSignal().Connect( this, &Capture::OnRenderFinished ); + mRenderTask.GetCameraActor().SetInvertYAxis( true ); + + mTimer = Dali::Timer::New( TIME_OUT_DURATION ); + mTimer.TickSignal().Connect( this, &Capture::OnTimeOut ); + mTimer.Start(); +} + +void Capture::UnsetRenderTask() +{ + DALI_ASSERT_ALWAYS(mCameraActor && "CameraActor is NULL."); + + 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."); + + Dali::RenderTaskList taskList = Dali::Stage::GetCurrent().GetRenderTaskList(); + Dali::RenderTask firstTask = taskList.GetTask( 0u ); + + // Stop rendering via frame-buffers as empty handle is used to clear target + firstTask.SetFrameBuffer( Dali::FrameBuffer() ); + + taskList.RemoveTask( mRenderTask ); + mRenderTask.Reset(); +} + +bool Capture::IsRenderTaskSetup() +{ + return mCameraActor && mRenderTask; +} + +void Capture::SetupResources( const Dali::Vector2& size, const Dali::Vector4& clearColor, Dali::Actor source ) +{ + CreateSurface( size ); + ClearSurface( size ); + + CreateNativeImageSource(); + + CreateFrameBuffer(); + + SetupRenderTask( source, clearColor ); +} + +void Capture::UnsetResources() +{ + if( IsRenderTaskSetup() ) + { + UnsetRenderTask(); + } + + if( IsFrameBufferCreated() ) + { + DeleteFrameBuffer(); + } + + if( IsNativeImageSourceCreated() ) + { + DeleteNativeImageSource(); + } + + if( IsSurfaceCreated() ) + { + DeleteSurface(); + } +} + +void Capture::OnRenderFinished( Dali::RenderTask& task ) +{ + Dali::Capture::FinishState state = Dali::Capture::FinishState::SUCCEEDED; + + mTimer.Stop(); + + if( !Save() ) + { + state = Dali::Capture::FinishState::FAILED; + DALI_LOG_ERROR("Fail to Capture mTbmSurface[%p] Path[%s]", mTbmSurface, mPath.c_str()); + } + + Dali::Capture handle( this ); + mFinishedSignal.Emit( handle, state ); + + UnsetResources(); + + // Decrease the reference count forcely. It is increased at Start(). + Unreference(); +} + +bool Capture::OnTimeOut() +{ + Dali::Capture::FinishState state = Dali::Capture::FinishState::FAILED; + + Dali::Capture handle( this ); + mFinishedSignal.Emit( handle, state ); + + 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 Adaptor + +} // End of namespace Internal + +} // End of namespace Dali diff --git a/adaptors/tizen/capture-impl.h b/adaptors/tizen/capture-impl.h new file mode 100755 index 0000000..040cfaf --- /dev/null +++ b/adaptors/tizen/capture-impl.h @@ -0,0 +1,254 @@ +#ifndef DALI_INTERNAL_CAPTURE_H +#define DALI_INTERNAL_CAPTURE_H + +/* + * Copyright (c) 2017 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 +#include +#include +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ + +class Capture; +typedef IntrusivePtr CapturePtr; + +class Capture : public BaseObject, public ConnectionTracker +{ +public: + /** + * @brief Constructor. + */ + Capture(); + + Capture( Dali::CameraActor cameraActor ); + + /** + * @copydoc Dali::Capture::New + */ + static CapturePtr New(); + + /** + * @copydoc Dali::Capture::New + */ + static CapturePtr New( Dali::CameraActor cameraActor ); + + /** + * @copydoc Dali::Capture::Start + */ + void Start( Dali::Actor source, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor ); + + /** + * @copydoc Dali::Capture::FinishedSignal + */ + Dali::Capture::CaptureFinishedSignalType& FinishedSignal(); + +protected: + + /** + * @brief Second-phase constructor. Must be called immediately after creating a new Capture; + */ + void Initialize(); + + /** + * @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 Dali::Vector2& size ); + + /** + * @brief Delete surface. + */ + void DeleteSurface(); + + /** + * @brief Clear surface with color. + * + * @param[in] size of clear aread. + */ + void ClearSurface( const Dali::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( Dali::Actor source, const Dali::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 Dali::Vector2& size, const Dali::Vector4& clearColor, Dali::Actor source ); + + /** + * @brief Unset resources for capture. + */ + void UnsetResources(); + + /** + * @brief Callback when render is finished. + * + * @param[in] task is used for capture. + */ + void OnRenderFinished( Dali::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: + Dali::Texture mNativeTexture; + Dali::FrameBuffer mFrameBuffer; + Dali::RenderTask mRenderTask; + Dali::Actor mParent; + Dali::Actor mSource; + Dali::CameraActor mCameraActor; + Dali::Timer mTimer; ///< For timeout. + Dali::Capture::CaptureFinishedSignalType mFinishedSignal; + std::string mPath; + Dali::NativeImageSourcePtr mNativeImageSourcePtr; ///< pointer to surface image + tbm_surface_h mTbmSurface; +}; + +} // End of namespace Adaptor +} // End of namespace Internal + +// Helpers for public-api forwarding methods + +inline Internal::Adaptor::Capture& GetImpl( Dali::Capture& captureWorker) +{ + DALI_ASSERT_ALWAYS( captureWorker && "Capture handle is empty" ); + + BaseObject& handle = captureWorker.GetBaseObject(); + + return static_cast< Internal::Adaptor::Capture& >( handle ); +} + +inline const Internal::Adaptor::Capture& GetImpl( const Dali::Capture& captureWorker ) +{ + DALI_ASSERT_ALWAYS( captureWorker && "Capture handle is empty" ); + + const BaseObject& handle = captureWorker.GetBaseObject(); + + return static_cast< const Internal::Adaptor::Capture& >( handle ); +} + +} // End of namespace Dali + +#endif // DALI_INTERNAL_CAPTURE_H diff --git a/adaptors/tizen/file.list b/adaptors/tizen/file.list index f7fb694..2d447ed 100644 --- a/adaptors/tizen/file.list +++ b/adaptors/tizen/file.list @@ -23,3 +23,6 @@ adaptor_tizen_internal_native_image_src_files = \ public_api_adaptor_tizen_header_files = \ $(adaptor_tizen_dir)/key-grab.h + +adaptor_tizen_internal_capture_src_files = \ + $(adaptor_tizen_dir)/capture-impl-tizen.cpp diff --git a/adaptors/wearable/capture/capture.cpp b/adaptors/wearable/capture/capture.cpp new file mode 100755 index 0000000..453c16c --- /dev/null +++ b/adaptors/wearable/capture/capture.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017 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 + +// INTERNAL HEADER +#include + +namespace Dali +{ + +Capture::Capture() +{ +} + +Capture Capture::New() +{ + Internal::Adaptor::CapturePtr internal = Internal::Adaptor::Capture::New(); + + return Capture( internal.Get() ); +} + +Capture Capture::New( Dali::CameraActor cameraActor ) +{ + Internal::Adaptor::CapturePtr internal = Internal::Adaptor::Capture::New( cameraActor ); + + return Capture( internal.Get() ); +} + +Capture Capture::DownCast( BaseHandle handle ) +{ + return Capture( dynamic_cast< Internal::Adaptor::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 ); +} + +void Capture::Start( Actor source, const Vector2& size, const std::string &path ) +{ + GetImpl( *this ).Start( source, size, path, Dali::Color::TRANSPARENT ); +} + +Capture::CaptureFinishedSignalType& Capture::FinishedSignal() +{ + return GetImpl( *this ).FinishedSignal(); +} + +Capture::Capture( Internal::Adaptor::Capture* internal ) +: BaseHandle( internal ) +{ +} + +} // namespace Dali diff --git a/adaptors/wearable/capture/capture.h b/adaptors/wearable/capture/capture.h new file mode 100644 index 0000000..635a1e0 --- /dev/null +++ b/adaptors/wearable/capture/capture.h @@ -0,0 +1,219 @@ +#ifndef DALI_CAPTURE_H +#define DALI_CAPTURE_H + +/* + * Copyright (c) 2017 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 HEADERS +#include +#include +#include + +// INTERNAL HEADERS + +namespace Dali +{ + +/** + * @addtogroup dali_adaptor_framework + * @{ + */ + +namespace Internal DALI_INTERNAL +{ +namespace Adaptor +{ +class Capture; +} +} + +/** + * @brief Capture snapshots the current scene and save as a file. + * + * @SINCE_1_3_4 + * + * 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, Capture::FinishState state ) + * { + * if ( state == Capture::FinishState::SUCCEEDED ) + * { + * // Do something + * } + * else + * { + * // Do something + * } + * } + * @endcode + */ +class DALI_IMPORT_API Capture : public BaseHandle +{ + +public: + + /** + * @brief The enumerations used for checking capture success + * @SINCE_1_3_4 + */ + enum class FinishState + { + SUCCEEDED, ///< Succeeded in saving the result after capture + FAILED ///< Failed to capture by time out or to save the result + }; + + /** + * @brief Typedef for finished signals sent by this class. + * + * @SINCE_1_3_4 + */ + typedef Signal< void ( Capture, Capture::FinishState ) > CaptureFinishedSignalType; + + /** + * @brief Create an uninitialized Capture; this can be initialized with Actor::New(). + * + * @SINCE_1_3_4 + * + * Calling member functions with an uninitialized Dali::Object is not allowed. + */ + Capture(); + + /** + * @brief Create an initialized Capture. + * + * @SINCE_1_3_4 + * + * @return A handle to a newly allocated Dali resource. + * @note Projection mode of default cameraActor is Dali::Camera::PERSPECTIVE_PROJECTION + */ + static Capture New(); + + /** + * @brief Create an initialized Capture. + * + * @SINCE_1_3_4 + * + * @param[in] cameraActor An initialized CameraActor. + * @return A handle to a newly allocated Dali resource. + */ + static Capture New( Dali::CameraActor cameraActor ); + + /** + * @brief Downcast an Object handle to Capture handle. + * + * @SINCE_1_3_4 + * + * 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. + * + * @SINCE_1_3_4 + * + * 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. + * + * @SINCE_1_3_4 + * + * @param[in] copy A reference to the copied handle. + */ + Capture( const Capture& copy ); + + /** + * @brief This assignment operator is required for (smart) pointer semantics. + * + * @SINCE_1_3_4 + * + * @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. + * + * @SINCE_1_3_4 + * + * @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 ); + + /** + * @brief Start capture and save the image as a file. + * + * @SINCE_1_3_4 + * + * @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. + * @note Clear color is transparent. + */ + void Start( Actor source, const Vector2& size, const std::string &path ); + + /** + * @brief Get finished signal. + * + * @SINCE_1_3_4 + * + * @return finished signal instance. + */ + CaptureFinishedSignalType& FinishedSignal(); + +public: // Not intended for application developers + /** + * @brief This constructor is used by New() methods. + * + * @SINCE_1_3_4 + * + * @param[in] internal A pointer to a newly allocated Dali resource. + */ + explicit DALI_INTERNAL Capture( Internal::Adaptor::Capture* internal ); +}; + +/** + * @} + */ + +} // namespace Dali + +#endif // DALI_CAPTURE_H diff --git a/adaptors/wearable/dali-wearable.h b/adaptors/wearable/dali-wearable.h index 15deb81..41081d8 100644 --- a/adaptors/wearable/dali-wearable.h +++ b/adaptors/wearable/dali-wearable.h @@ -20,5 +20,6 @@ // INTERNAL INCLUDES #include +#include -#endif // __DALI_WEARABLE_H__ \ No newline at end of file +#endif // __DALI_WEARABLE_H__ diff --git a/adaptors/wearable/file.list b/adaptors/wearable/file.list index 0075500..5a870fa 100644 --- a/adaptors/wearable/file.list +++ b/adaptors/wearable/file.list @@ -3,7 +3,8 @@ adaptor_internal_wearable_profile_src_files = \ $(adaptor_wearable_dir)/watch-application-impl.cpp \ $(adaptor_wearable_dir)/watch/watch-application.cpp \ - $(adaptor_wearable_dir)/watch/watch-time.cpp + $(adaptor_wearable_dir)/watch/watch-time.cpp \ + $(adaptor_wearable_dir)/capture/capture.cpp adaptor_dali_wearable_header_file = \ $(adaptor_wearable_dir)/dali-wearable.h @@ -11,3 +12,6 @@ adaptor_dali_wearable_header_file = \ public_dali_watch_header_files = \ $(adaptor_wearable_dir)/watch/watch-application.h \ $(adaptor_wearable_dir)/watch/watch-time.h + +public_dali_capture_header_files = \ + $(adaptor_wearable_dir)/capture/capture.h diff --git a/build/tizen/adaptor/Makefile.am b/build/tizen/adaptor/Makefile.am index eaeb652..14ea0e9 100644 --- a/build/tizen/adaptor/Makefile.am +++ b/build/tizen/adaptor/Makefile.am @@ -193,7 +193,8 @@ endif # USE_ECORE_WAYLAND adaptor_internal_src_files += $(adaptor_tizen_internal_egl_extension_src_files) \ $(adaptor_tizen_internal_native_image_src_files) \ - $(adaptor_internal_wearable_profile_src_files) + $(adaptor_internal_wearable_profile_src_files) \ + $(adaptor_tizen_internal_capture_src_files) else adaptor_internal_src_files += $(adaptor_x11_tizen_internal_src_files) \ $(adaptor_common_internal_egl_extension_src_files) \ @@ -352,6 +353,12 @@ LIBDALI_ADAPTOR_LA_includes += \ -I../../../adaptors/tizen endif +if WEARABLE_PROFILE +LIBDALI_ADAPTOR_LA_includes += \ + -I../../../adaptors/wearable \ + -I../../../adaptors/wearable/capture +endif + daliDefaultThemeDir = ${dataReadWriteDir}/theme/ daliShaderbinCacheDir = ${dataReadOnlyDir}/core/shaderbin/ @@ -585,6 +592,9 @@ tizenadaptorpublicapi_HEADERS += $(adaptor_dali_wearable_header_file) tizenwatchpublicapidir = $(tizenadaptorpublicapidir)/watch tizenwatchpublicapi_HEADERS = $(public_dali_watch_header_files) +tizencapturepublicapidir = $(tizenadaptorpublicapidir)/capture +tizencapturepublicapi_HEADERS = $(public_dali_capture_header_files) + if USE_APPFW if USE_APPFW_EFL_BASE else