Fix bug in TextureSet
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / texture-set-impl.cpp
1 /*
2  * Copyright (c) 2016 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/rendering/texture-set-impl.h> // Dali::Internal::TextureSet
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
24 #include <dali/internal/update/manager/update-manager.h>
25 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
26
27 namespace Dali
28 {
29 namespace Internal
30 {
31
32 TextureSetPtr TextureSet::New()
33 {
34   TextureSetPtr textureSet( new TextureSet() );
35   textureSet->Initialize();
36   return textureSet;
37 }
38
39 void TextureSet::SetImage( size_t index, ImagePtr image )
40 {
41   if( !mNewTextures.empty() )
42   {
43     DALI_LOG_ERROR( "Error: Cannot mix images and textures in the same TextureSet\n");
44     return;
45   }
46
47   size_t textureCount( mImages.size() );
48   if( index < textureCount )
49   {
50     if( mImages[index] && mOnStage )
51     {
52       mImages[index]->Disconnect();
53     }
54   }
55   else
56   {
57     mImages.resize(index + 1);
58
59     bool samplerExist = true;
60     if( mSamplers.size() < index + 1 )
61     {
62       mSamplers.resize( index + 1 );
63       samplerExist = false;
64     }
65
66     mSamplers.resize(index + 1);
67     for( size_t i(textureCount); i<=index; ++i )
68     {
69       mImages[i] = NULL;
70
71       if( !samplerExist )
72       {
73         mSamplers[i] = NULL;
74       }
75     }
76   }
77   mImages[index] = image;
78
79
80   if( image )
81   {
82     if( mOnStage )
83     {
84       image->Connect();
85     }
86     SceneGraph::SetImageMessage( mEventThreadServices, *mSceneObject, index, image->GetResourceId() );
87   }
88   else
89   {
90     SceneGraph::SetImageMessage( mEventThreadServices, *mSceneObject, index, Integration::InvalidResourceId );
91   }
92 }
93
94 void TextureSet::SetTexture( size_t index, NewTexturePtr texture )
95 {
96   if( !mImages.empty() )
97   {
98     DALI_LOG_ERROR( "Error: Cannot mix images and textures in the same texture set\n");
99     return;
100   }
101
102   size_t textureCount( mNewTextures.size() );
103   if( index >= textureCount )
104   {
105     mNewTextures.resize(index + 1);
106
107     bool samplerExist = true;
108     if( mSamplers.size() < index + 1 )
109     {
110       mSamplers.resize( index + 1 );
111       samplerExist = false;
112     }
113
114     for( size_t i(textureCount); i<=index; ++i )
115     {
116       mNewTextures[i] = NULL;
117
118       if( !samplerExist )
119       {
120         mSamplers[i] = NULL;
121       }
122     }
123   }
124
125   mNewTextures[index]= texture;
126
127   Render::NewTexture* renderTexture(0);
128   if( texture )
129   {
130     renderTexture = texture->GetRenderObject();
131   }
132
133   SceneGraph::SetTextureMessage( mEventThreadServices, *mSceneObject, index, renderTexture );
134 }
135
136 Image* TextureSet::GetImage( size_t index ) const
137 {
138   Image* result(0);
139   if( index < mImages.size() )
140   {
141     result = mImages[index].Get();
142   }
143   else
144   {
145     DALI_LOG_ERROR( "Error: Invalid index to TextureSet::GetImage\n");
146   }
147
148   return result;
149 }
150
151 NewTexture* TextureSet::GetTexture( size_t index ) const
152 {
153   NewTexture* result(0);
154   if( index < mNewTextures.size() )
155   {
156     result = mNewTextures[index].Get();
157   }
158   else
159   {
160     DALI_LOG_ERROR( "Error: Invalid index to TextureSet::GetTexture\n");
161   }
162
163   return result;
164 }
165
166 void TextureSet::SetSampler( size_t index, SamplerPtr sampler )
167 {
168   size_t samplerCount( mSamplers.size() );
169   if( samplerCount < index + 1  )
170   {
171     mSamplers.resize( index + 1 );
172     for( size_t i(samplerCount); i<=index; ++i )
173     {
174       mSamplers[i] = NULL;
175     }
176   }
177
178   mSamplers[index] = sampler;
179
180   Render::Sampler* renderSampler(0);
181   if( sampler )
182   {
183     renderSampler = sampler->GetSamplerRenderObject();
184   }
185
186   SceneGraph::SetSamplerMessage( mEventThreadServices, *mSceneObject, index, renderSampler );
187 }
188
189 Sampler* TextureSet::GetSampler( size_t index ) const
190 {
191   Sampler* result(0);
192   if( index < mSamplers.size() )
193   {
194     result = mSamplers[index].Get();
195   }
196   else
197   {
198     DALI_LOG_ERROR( "Error: Invalid index to TextureSet::GetSampler\n");
199   }
200
201   return result;
202 }
203
204 size_t TextureSet::GetTextureCount() const
205 {
206   return mImages.size() + mNewTextures.size();
207 }
208
209 const SceneGraph::TextureSet* TextureSet::GetTextureSetSceneObject() const
210 {
211   return mSceneObject;
212 }
213
214 bool TextureSet::OnStage() const
215 {
216   return mOnStage;
217 }
218
219 void TextureSet::Connect()
220 {
221   mOnStage = true;
222
223   for( size_t i(0); i<mImages.size(); ++i )
224   {
225     if( mImages[i] )
226     {
227       mImages[i]->Connect();
228       SceneGraph::SetImageMessage( mEventThreadServices, *mSceneObject, i, mImages[i]->GetResourceId() );
229     }
230     else
231     {
232       SceneGraph::SetImageMessage( mEventThreadServices, *mSceneObject, i, Integration::InvalidResourceId );
233     }
234   }
235 }
236
237 void TextureSet::Disconnect()
238 {
239   for( size_t i(0); i<mImages.size(); ++i )
240   {
241     if( mImages[i] )
242     {
243       mImages[i]->Disconnect();
244     }
245   }
246
247   mOnStage = false;
248 }
249
250 TextureSet::TextureSet()
251 :mEventThreadServices( *Stage::GetCurrent() ),
252  mSceneObject( NULL ),
253  mOnStage( false )
254 {
255 }
256
257 void TextureSet::Initialize()
258 {
259   SceneGraph::UpdateManager& updateManager = mEventThreadServices.GetUpdateManager();
260
261   mSceneObject = SceneGraph::TextureSet::New();
262   AddTextureSetMessage( updateManager, *mSceneObject );
263 }
264
265 TextureSet::~TextureSet()
266 {
267   if( EventThreadServices::IsCoreRunning() )
268   {
269     SceneGraph::UpdateManager& updateManager = mEventThreadServices.GetUpdateManager();
270     RemoveTextureSetMessage( updateManager, *mSceneObject );
271   }
272 }
273
274 } // namespace Internal
275 } // namespace Dali