2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/system/common/capture-impl.h>
24 #include <dali/public-api/common/stage.h>
25 #include <dali/public-api/common/vector-wrapper.h>
26 #include <dali/public-api/render-tasks/render-task-list.h>
27 #include <dali/integration-api/debug.h>
30 #include <dali/integration-api/adaptor-framework/adaptor.h>
34 unsigned int TIME_OUT_DURATION = 1000;
49 mNativeImageSourcePtr( NULL ),
54 Capture::Capture( Dali::CameraActor cameraActor )
55 : mCameraActor( cameraActor ),
58 mNativeImageSourcePtr( NULL ),
65 DeleteNativeImageSource();
68 CapturePtr Capture::New()
70 CapturePtr pWorker = new Capture();
75 CapturePtr Capture::New( Dali::CameraActor cameraActor )
77 CapturePtr pWorker = new Capture( cameraActor );
82 void Capture::Start( Dali::Actor source, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor )
84 DALI_ASSERT_ALWAYS(path.size() > 4 && "Path is invalid.");
86 // Increase the reference count focely to avoid application mistake.
90 if( mPath.size() > 0 )
95 DALI_ASSERT_ALWAYS(source && "Source is NULL.");
98 SetupResources( size, clearColor, source );
101 Dali::NativeImageSourcePtr Capture::GetNativeImageSource() const
103 DALI_ASSERT_ALWAYS( mNativeImageSourcePtr && "mNativeImageSourcePtr is NULL.");
105 return mNativeImageSourcePtr;
108 Dali::Capture::CaptureFinishedSignalType& Capture::FinishedSignal()
110 return mFinishedSignal;
113 void Capture::CreateNativeImageSource( const Vector2& size )
115 Dali::Adaptor& adaptor = Dali::Adaptor::Get();
117 DALI_ASSERT_ALWAYS(adaptor.IsAvailable() && "Dali::Adaptor is not available.");
119 DALI_ASSERT_ALWAYS(!mNativeImageSourcePtr && "NativeImageSource is already created.");
121 // create the NativeImageSource object with our surface
122 mNativeImageSourcePtr = Dali::NativeImageSource::New( size.width, size.height, Dali::NativeImageSource::COLOR_DEPTH_DEFAULT );
125 void Capture::DeleteNativeImageSource()
127 DALI_ASSERT_ALWAYS(mNativeImageSourcePtr && "mNativeImageSource is NULL.");
129 mNativeImageSourcePtr.Reset();
132 bool Capture::IsNativeImageSourceCreated()
134 return mNativeImageSourcePtr;
137 void Capture::CreateFrameBuffer()
139 DALI_ASSERT_ALWAYS(mNativeImageSourcePtr && "NativeImageSource is NULL.");
141 DALI_ASSERT_ALWAYS(!mFrameBuffer && "FrameBuffer is already created.");
143 mNativeTexture = Dali::Texture::New( *mNativeImageSourcePtr );
145 // Create a FrameBuffer object with depth attachments.
146 mFrameBuffer = Dali::FrameBuffer::New( mNativeTexture.GetWidth(), mNativeTexture.GetHeight(), Dali::FrameBuffer::Attachment::DEPTH );
147 // Add a color attachment to the FrameBuffer object.
148 mFrameBuffer.AttachColorTexture( mNativeTexture );
151 void Capture::DeleteFrameBuffer()
153 DALI_ASSERT_ALWAYS(mFrameBuffer && "FrameBuffer is NULL.");
155 mFrameBuffer.Reset();
156 mNativeTexture.Reset();
159 bool Capture::IsFrameBufferCreated()
164 void Capture::SetupRenderTask( Dali::Actor source, const Dali::Vector4& clearColor )
166 DALI_ASSERT_ALWAYS(source && "Source is empty.");
170 // Check the original parent about source.
171 mParent = mSource.GetParent();
173 Dali::Stage stage = Dali::Stage::GetCurrent();
174 Dali::Size stageSize = stage.GetSize();
176 // Add to stage for rendering the source. If source isn't on the stage then it never be rendered.
177 stage.Add( mSource );
181 mCameraActor = Dali::CameraActor::New( stageSize );
182 mCameraActor.SetParentOrigin( ParentOrigin::CENTER );
183 mCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
186 stage.Add( mCameraActor );
188 DALI_ASSERT_ALWAYS(mFrameBuffer && "Framebuffer is NULL.");
190 DALI_ASSERT_ALWAYS(!mRenderTask && "RenderTask is already created.");
192 Dali::RenderTaskList taskList = stage.GetRenderTaskList();
193 mRenderTask = taskList.CreateTask();
194 mRenderTask.SetRefreshRate( Dali::RenderTask::REFRESH_ONCE );
195 mRenderTask.SetSourceActor( source );
196 mRenderTask.SetCameraActor( mCameraActor );
197 mRenderTask.SetScreenToFrameBufferFunction( Dali::RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION );
198 mRenderTask.SetFrameBuffer( mFrameBuffer );
199 mRenderTask.SetClearColor( clearColor );
200 mRenderTask.SetClearEnabled( true );
201 mRenderTask.SetProperty( Dali::RenderTask::Property::REQUIRES_SYNC, true );
202 mRenderTask.FinishedSignal().Connect( this, &Capture::OnRenderFinished );
203 mRenderTask.GetCameraActor().SetInvertYAxis( true );
205 mTimer = Dali::Timer::New( TIME_OUT_DURATION );
206 mTimer.TickSignal().Connect( this, &Capture::OnTimeOut );
210 void Capture::UnsetRenderTask()
212 DALI_ASSERT_ALWAYS(mCameraActor && "CameraActor is NULL.");
216 // Restore the parent of source.
217 mParent.Add( mSource );
229 mCameraActor.Unparent();
230 mCameraActor.Reset();
232 DALI_ASSERT_ALWAYS( mRenderTask && "RenderTask is NULL." );
234 Dali::RenderTaskList taskList = Dali::Stage::GetCurrent().GetRenderTaskList();
235 taskList.RemoveTask( mRenderTask );
239 bool Capture::IsRenderTaskSetup()
241 return mCameraActor && mRenderTask;
244 void Capture::SetupResources( const Dali::Vector2& size, const Dali::Vector4& clearColor, Dali::Actor source )
246 CreateNativeImageSource( size );
250 SetupRenderTask( source, clearColor );
253 void Capture::UnsetResources()
255 if( IsRenderTaskSetup() )
260 if( IsFrameBufferCreated() )
266 void Capture::OnRenderFinished( Dali::RenderTask& task )
268 Dali::Capture::FinishState state = Dali::Capture::FinishState::SUCCEEDED;
276 state = Dali::Capture::FinishState::FAILED;
277 DALI_LOG_ERROR( "Fail to Capture Path[%s]", mPath.c_str() );
281 Dali::Capture handle( this );
282 mFinishedSignal.Emit( handle, state );
286 // Decrease the reference count forcely. It is increased at Start().
290 bool Capture::OnTimeOut()
292 Dali::Capture::FinishState state = Dali::Capture::FinishState::FAILED;
294 Dali::Capture handle( this );
295 mFinishedSignal.Emit( handle, state );
299 // Decrease the reference count forcely. It is increased at Start().
305 bool Capture::SaveFile()
307 DALI_ASSERT_ALWAYS(mNativeImageSourcePtr && "mNativeImageSourcePtr is NULL");
309 return mNativeImageSourcePtr->EncodeToFile( mPath );
312 } // End of namespace Adaptor
314 } // End of namespace Internal
316 } // End of namespace Dali