[Tizen] Add OffscreenApplication
[platform/core/uifw/dali-adaptor.git] / dali / internal / offscreen / tizen / offscreen-window-impl-tizen.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // EXTERNAL INCLUDES
19 #include <dali/devel-api/adaptor-framework/clipboard.h>
20 #include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
21 #include <dali/integration-api/adaptor-framework/adaptor.h>
22 #include <dali/integration-api/adaptor-framework/native-render-surface.h>
23 #include <dali/integration-api/adaptor-framework/native-render-surface-factory.h>
24 #include <dali/integration-api/adaptor-framework/trigger-event-factory.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/public-api/actors/layer.h>
27 #include <tbm_surface.h>
28 #include <tbm_surface_queue.h>
29
30 // INTERNAL INCLUDES
31 #include <dali/internal/offscreen/common/offscreen-application-impl.h>
32
33 // CLASS HEADER
34 #include <dali/internal/offscreen/tizen/offscreen-window-impl-tizen.h>
35
36 namespace Dali
37 {
38
39 namespace Internal
40 {
41
42 OffscreenWindowTizen* OffscreenWindowTizen::New( uint16_t width, uint16_t height, Dali::Any surface, bool isTranslucent )
43 {
44   OffscreenWindowTizen* window = new OffscreenWindowTizen( width, height, surface, isTranslucent );
45   return window;
46 }
47
48 OffscreenWindowTizen::OffscreenWindowTizen( uint16_t width, uint16_t height, Dali::Any surface, bool isTranslucent )
49 : mAdaptor( nullptr ),
50   mRenderNotification(),
51   mIsTranslucent( isTranslucent )
52 {
53   // Create surface
54   if ( surface.Empty() )
55   {
56     mSurface = std::unique_ptr< RenderSurfaceInterface >( CreateNativeSurface( SurfaceSize( width, height ), surface, isTranslucent ) );
57   }
58   else
59   {
60     width = static_cast<uint16_t>( tbm_surface_queue_get_width( AnyCast< tbm_surface_queue_h > ( surface ) ) );
61     height = static_cast<uint16_t>( tbm_surface_queue_get_height( AnyCast< tbm_surface_queue_h > ( surface ) ) );
62     mSurface = std::unique_ptr< RenderSurfaceInterface >( CreateNativeSurface( SurfaceSize( width, height ), surface, isTranslucent ) );
63   }
64 }
65
66 void OffscreenWindowTizen::Initialize( OffscreenApplication* offscreenApplication, bool isDefaultWindow )
67 {
68   mAdaptor = offscreenApplication->GetAdaptor();
69
70   DALI_ASSERT_ALWAYS( mAdaptor && "OffscreenWindowTizen can not be created when the Adaptor is null" );
71
72   if( isDefaultWindow )
73   {
74     Initialize();
75     return;
76   }
77
78   if( offscreenApplication->GetState() != OffscreenApplication::RUNNING )
79   {
80     offscreenApplication->PreInitSignal().Connect( this, &OffscreenWindowTizen::OnPreInitOffscreenApplication );
81
82     return;
83   }
84
85   Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
86   mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
87
88   Initialize();
89 }
90
91 void OffscreenWindowTizen::Initialize()
92 {
93   // Connect callback to be notified when the surface is rendered
94   TriggerEventFactory triggerEventFactory;
95
96   mRenderNotification = std::unique_ptr< TriggerEventInterface >( triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &OffscreenWindowTizen::OnPostRender ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) );
97
98   NativeRenderSurface* surface = GetNativeRenderSurface();
99
100   if( !surface )
101   {
102     return;
103   }
104
105   surface->SetRenderNotification( mRenderNotification.get() );
106 }
107
108 void OffscreenWindowTizen::OnPreInitOffscreenApplication()
109 {
110   Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
111   mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
112
113   Initialize();
114 }
115
116 OffscreenWindowTizen::~OffscreenWindowTizen()
117 {
118   NativeRenderSurface* surface = GetNativeRenderSurface();
119
120   if( surface )
121   {
122     // To prevent notification triggering in NativeRenderSurface::PostRender while deleting SceneHolder
123     surface->SetRenderNotification( nullptr );
124   }
125 }
126
127 uint32_t OffscreenWindowTizen::GetLayerCount() const
128 {
129   return mScene.GetLayerCount();
130 }
131
132 Dali::Layer OffscreenWindowTizen::GetLayer( uint32_t depth ) const
133 {
134   return mScene.GetLayer( depth );
135 }
136
137 OffscreenWindowTizen::WindowSize OffscreenWindowTizen::GetSize() const
138 {
139   Size size = mScene.GetSize();
140
141   return OffscreenWindowTizen::WindowSize( static_cast<uint16_t>( size.width ), static_cast<uint16_t>( size.height ) );
142 }
143
144 Dali::Any OffscreenWindowTizen::GetNativeHandle() const
145 {
146   // TODO: What do I have to return?
147 }
148
149 NativeRenderSurface* OffscreenWindowTizen::GetNativeRenderSurface() const
150 {
151   return dynamic_cast< NativeRenderSurface* >( mSurface.get() );
152 }
153
154 void OffscreenWindowTizen::OnPostRender()
155 {
156   NativeRenderSurface* surface = GetNativeRenderSurface();
157
158   if( !surface )
159   {
160     return;
161   }
162
163   tbm_surface_h tbmSurface = AnyCast<tbm_surface_h>( surface->GetDrawable() );
164   
165   if ( tbmSurface )
166   {
167     mPostRenderSignal.Emit( Dali::OffscreenWindow( this ), AnyCast<tbm_surface_h>( tbmSurface ) );
168   }
169
170   surface->ReleaseLock();
171 }
172
173 OffscreenWindow::PostRenderSignalType& OffscreenWindowTizen::PostRenderSignal()
174 {
175   return mPostRenderSignal;
176 }
177
178 } // namespace Internal
179
180 } // namespace Dali