Change RenderTaskList to behave like any other SceneGraph object
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / layer-list.cpp
1 /*
2  * Copyright (c) 2018 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 // CLASS HEADER
19 #include <dali/internal/event/actors/layer-list.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>  // for std::swap
23
24 // INTERNAL INCLUDES
25 #include <dali/integration-api/debug.h>
26 #include <dali/internal/event/actors/layer-impl.h>
27 #include <dali/internal/update/manager/update-manager.h>
28
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 namespace // unnamed namespace
36 {
37
38 typedef std::vector<Layer*> LayerContainer;
39 typedef LayerContainer::iterator LayerIter;
40 typedef LayerContainer::reverse_iterator ReverseLayerIter;
41
42 /**
43  * A private helper template to return an iterator to the layer passed in.
44  * @param[in] first position to start searching from
45  * @param[in] last position to search to
46  * @param[in] layer to search for
47  * @return iterator to layer if found
48  */
49 template<class InputIterator> InputIterator Find( InputIterator first, InputIterator last, const Layer& layer )
50 {
51   for( ; first != last ; ++first )
52   {
53     if( *first == &layer )
54     {
55       break;
56     }
57  }
58  return first;
59 }
60
61 } // unnamed namespace
62
63 LayerList* LayerList::New( SceneGraph::UpdateManager& updateManager )
64 {
65   return new LayerList( updateManager );
66 }
67
68 LayerList::~LayerList()
69 {
70 }
71
72 uint32_t LayerList::GetLayerCount() const
73 {
74   return static_cast<uint32_t>( mLayers.size() ); //  // only 4,294,967,295 layers supported
75 }
76
77 Layer* LayerList::GetLayer( uint32_t depth ) const
78 {
79   DALI_ASSERT_ALWAYS( depth < mLayers.size() );
80
81   return mLayers[ depth ];
82 }
83
84 uint32_t LayerList::GetDepth( const Layer* layer ) const
85 {
86   for( uint32_t count = 0; count < mLayers.size(); ++count )
87   {
88     if( layer == mLayers[ count ] )
89     {
90       return count;
91     }
92   }
93   return 0;
94 }
95
96 void LayerList::RegisterLayer(Layer& layer)
97 {
98   DALI_ASSERT_DEBUG(  mLayers.end() == Find( mLayers.begin(), mLayers.end(), layer) );
99   mLayers.push_back(&layer);
100
101   SetLayerDepths();
102 }
103
104 void LayerList::UnregisterLayer(Layer& layer)
105 {
106   // Find the layer...
107   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
108   DALI_ASSERT_DEBUG(iter != mLayers.end());
109
110   // ...and remove it
111   mLayers.erase(iter);
112
113   SetLayerDepths();
114 }
115
116 void LayerList::RaiseLayer(Layer& raiseLayer)
117 {
118   LayerIter iter = Find( mLayers.begin(), mLayers.end(), raiseLayer);
119
120   if (iter   != mLayers.end() &&
121       iter+1 != mLayers.end())
122   {
123     LayerIter nextIter = iter+1;
124
125     // Swap the pointers
126     std::swap(*iter, *nextIter);
127
128     SetLayerDepths();
129   }
130 }
131
132 void LayerList::LowerLayer(Layer& lowerLayer)
133 {
134   ReverseLayerIter iter =  Find( mLayers.rbegin(), mLayers.rend(), lowerLayer);
135
136   if (iter   != mLayers.rend() &&
137       iter+1 != mLayers.rend())
138   {
139     ReverseLayerIter nextIter = iter+1;
140
141     // Swap the pointers
142     std::swap(*iter, *nextIter);
143
144     SetLayerDepths();
145   }
146 }
147
148 void LayerList::RaiseLayerToTop( const Layer& layer )
149 {
150   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
151
152   if (iter   != mLayers.end() &&
153       iter+1 != mLayers.end())
154   {
155     Layer* raised = *iter;
156
157     copy(iter+1, mLayers.end(), iter);
158     mLayers.back() = raised;
159
160     SetLayerDepths();
161   }
162 }
163
164 void LayerList::LowerLayerToBottom( const Layer& layer )
165 {
166   ReverseLayerIter iter =  Find( mLayers.rbegin(), mLayers.rend(), layer);
167
168   if (iter   != mLayers.rend() &&
169       iter+1 != mLayers.rend())
170   {
171     Layer* lowered = *iter;
172
173     copy(iter+1, mLayers.rend(), iter);
174     mLayers.front() = lowered;
175
176     SetLayerDepths();
177   }
178 }
179
180 void LayerList::MoveLayerAbove( const Layer& layer, const Layer& target )
181 {
182   // check if it already is
183   if( layer.GetDepth() == ( target.GetDepth() + 1 ) )
184   {
185     return;
186   }
187
188   // find the layer to move
189   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
190
191   if( iter != mLayers.end() )
192   {
193     Layer* moved = *iter;
194     mLayers.erase( iter );
195     // find target
196     LayerIter iterT = Find( mLayers.begin(), mLayers.end(), target);
197     // if target is not found there's a programming error somewhere
198     DALI_ASSERT_DEBUG( iterT != mLayers.end() );
199     // iterT might be the last
200     if( ( iterT+1 ) == mLayers.end() )
201     {
202       mLayers.push_back( moved );
203     }
204     else
205     {
206       mLayers.insert( iterT+1, moved );
207     }
208
209     SetLayerDepths();
210   }
211 }
212
213 void LayerList::MoveLayerBelow( const Layer& layer, const Layer& target )
214 {
215   // check if it already is in correct order
216   if( layer.GetDepth() == ( target.GetDepth() - 1 ) )
217   {
218     return;
219   }
220
221   // find the layer to move
222   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
223   if( iter != mLayers.end() )
224   {
225     Layer* moved = *iter;
226     mLayers.erase( iter );
227     // find target
228     LayerIter iterT = Find( mLayers.begin(), mLayers.end(), target);
229     // if target is not found there's a programming error somewhere
230     DALI_ASSERT_DEBUG( iterT != mLayers.end() );
231     mLayers.insert( iterT, moved );
232
233     SetLayerDepths();
234   }
235 }
236
237 LayerList::LayerList( SceneGraph::UpdateManager& updateManager )
238 : mUpdateManager( updateManager ),
239   mRoot( NULL )
240 {
241 }
242
243 void LayerList::SetLayerDepths()
244 {
245   // we've got a list of on-stage layers on actor side, need to get their stage
246   // pointers so we can send them to the update manager
247   std::vector< SceneGraph::Layer* > layers;
248   layers.reserve( mLayers.size() );
249
250   // Set the layers (possibly) new depth
251   for (LayerIter iter = mLayers.begin(); iter != mLayers.end(); ++iter)
252   {
253     SceneGraph::Layer* layerPtr = const_cast< SceneGraph::Layer* >( &( (*iter)->GetSceneLayerOnStage() ) );
254     layers.push_back( layerPtr );
255   }
256
257   // Layers are being used in a separate thread; queue a message to set order
258   SetLayerDepthsMessage( mUpdateManager, layers, &( mRoot->GetSceneLayerOnStage() ) );
259 }
260
261 void LayerList::SetRootLayer(Layer* rootLayer)
262 {
263   mRoot = rootLayer;
264
265   SetLayerDepths();
266 }
267
268 } // namespace Internal
269
270 } // namespace Dali