Merge branch 'tizen' of platform/core/uifw/dali-core into devel/new_mesh
[platform/core/uifw/dali-core.git] / dali / internal / event / actor-attachments / image-attachment-impl.cpp
1 /*
2  * Copyright (c) 2014 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/actor-attachments/image-attachment-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/internal/event/common/event-thread-services.h>
24 #include <dali/internal/update/manager/update-manager.h>
25 #include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
26 #include <dali/internal/event/effects/shader-effect-impl.h>
27 #include <dali/internal/render/shaders/scene-graph-shader.h>
28
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 ImageAttachmentPtr ImageAttachment::New( EventThreadServices& eventThreadServices, const SceneGraph::Node& parentNode )
36 {
37   ImageAttachmentPtr attachment( new ImageAttachment( eventThreadServices ) );
38
39   // Transfer object ownership of scene-object to message
40   SceneGraph::ImageAttachment* sceneObject = CreateSceneObject();
41   AttachToNodeMessage( eventThreadServices.GetUpdateManager(), parentNode, sceneObject );
42
43   // Keep raw pointer for message passing
44   attachment->mSceneObject = sceneObject;
45
46   return attachment;
47 }
48
49 ImageAttachment::ImageAttachment( EventThreadServices& eventThreadServices )
50 : RenderableAttachment(eventThreadServices),
51   mSceneObject(NULL),
52   mPixelArea(0,0,0,0),
53   mStyle(Dali::ImageActor::STYLE_QUAD),
54   mBorder(0.45,0.45,0.1,0.1),
55   mIsPixelAreaSet(false),
56   mBorderInPixels(false),
57
58
59   mBlendingOptions(),
60   mSamplerBitfield( ImageSampler::PackBitfield( FilterMode::DEFAULT, FilterMode::DEFAULT ) ),
61   mSortModifier( 0.0f ),
62   mCullFaceMode( CullNone ),
63   mBlendingMode( BlendingMode::AUTO ),
64   mShaderEffect()
65 {
66   mImageConnectable.Set( NULL, false );
67 }
68
69 ImageAttachment::~ImageAttachment()
70 {
71 }
72
73 void ImageAttachment::SetImage( ImagePtr& image )
74 {
75   bool onStage = OnStage();
76   // keep a reference to Image object
77   mImageConnectable.Set( image, onStage );
78
79   // Wait until the scene-graph attachment is connected, before providing resource ID
80   if ( OnStage() )
81   {
82     unsigned int resourceId = (image) ? image->GetResourceId() : 0u;
83
84     // sceneObject is being used in a separate thread; queue a message to set
85     SetTextureIdMessage( GetEventThreadServices(), *mSceneObject, resourceId );
86   }
87 }
88
89 ImagePtr ImageAttachment::GetImage()
90 {
91   return mImageConnectable.Get();
92 }
93
94 void ImageAttachment::SetPixelArea(const PixelArea& pixelArea)
95 {
96   // check to see if pixel area is actually different, using rect::operator==
97   if( pixelArea != mPixelArea )
98   {
99     // Cache for public getters
100     mPixelArea = pixelArea;
101     mIsPixelAreaSet = true;
102
103     // sceneObject is being used in a separate thread; queue a message to set
104     SetPixelAreaMessage( GetEventThreadServices(), *mSceneObject, mPixelArea );
105   }
106 }
107
108 void ImageAttachment::ClearPixelArea()
109 {
110   // Cache for public getters
111   mIsPixelAreaSet = false;
112
113   // sceneObject is being used in a separate thread; queue a message to set
114   ClearPixelAreaMessage( GetEventThreadServices(), *mSceneObject );
115 }
116
117 void ImageAttachment::SetStyle(Style style)
118 {
119   // Cache for public getters
120   mStyle = style;
121
122   // sceneObject is being used in a separate thread; queue a message to set
123   SetStyleMessage( GetEventThreadServices(), *mSceneObject, style );
124 }
125
126 void ImageAttachment::SetNinePatchBorder(const Vector4& border, bool inPixels)
127 {
128   // Cache for public getters
129   mBorder = border;
130   mBorderInPixels = inPixels;
131
132   // sceneObject is being used in a separate thread; queue a message to set
133   SetNinePatchBorderMessage( GetEventThreadServices(), *mSceneObject, border, inPixels );
134 }
135
136 SceneGraph::ImageAttachment* ImageAttachment::CreateSceneObject()
137 {
138   return SceneGraph::ImageAttachment::New( 0u );
139 }
140
141 const SceneGraph::ImageAttachment& ImageAttachment::GetSceneObject() const
142 {
143   DALI_ASSERT_DEBUG( mSceneObject != NULL );
144   return *mSceneObject;
145 }
146
147 void ImageAttachment::SetSortModifier(float modifier)
148 {
149   // Cache for actor-side getters
150   mSortModifier = modifier;
151
152   // attachment is being used in a separate thread; queue a message to set the value & base value
153   SetSortModifierMessage( GetEventThreadServices(), GetSceneObject(), modifier );
154 }
155
156 float ImageAttachment::GetSortModifier() const
157 {
158   // mSortModifier is not animatable; this is the most up-to-date value.
159   return mSortModifier;
160 }
161
162 void ImageAttachment::SetCullFace( CullFaceMode mode )
163 {
164   // Cache for actor-side getters
165   mCullFaceMode = mode;
166
167   // attachment is being used in a separate thread; queue a message to set the value
168   SetCullFaceMessage( GetEventThreadServices(), GetSceneObject(), mode );
169 }
170
171 CullFaceMode ImageAttachment::GetCullFace() const
172 {
173   // mCullFaceMode is not animatable; this is the most up-to-date value.
174   return mCullFaceMode;
175 }
176
177 void ImageAttachment::SetBlendMode( BlendingMode::Type mode )
178 {
179   mBlendingMode = mode;
180
181   // attachment is being used in a separate thread; queue a message to set the value
182   SetBlendingModeMessage( GetEventThreadServices(), GetSceneObject(), mode );
183 }
184
185 BlendingMode::Type ImageAttachment::GetBlendMode() const
186 {
187   return mBlendingMode;
188 }
189
190 void ImageAttachment::SetBlendFunc( BlendingFactor::Type srcFactorRgb,   BlendingFactor::Type destFactorRgb,
191                                          BlendingFactor::Type srcFactorAlpha, BlendingFactor::Type destFactorAlpha )
192 {
193   // Cache for actor-side getters
194   mBlendingOptions.SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
195
196   // attachment is being used in a separate thread; queue a message to set the value
197   SetBlendingOptionsMessage( GetEventThreadServices(), GetSceneObject(), mBlendingOptions.GetBitmask() );
198 }
199
200 void ImageAttachment::GetBlendFunc( BlendingFactor::Type& srcFactorRgb,   BlendingFactor::Type& destFactorRgb,
201                                          BlendingFactor::Type& srcFactorAlpha, BlendingFactor::Type& destFactorAlpha ) const
202 {
203   // These are not animatable, the cached values are up-to-date.
204   srcFactorRgb    = mBlendingOptions.GetBlendSrcFactorRgb();
205   destFactorRgb   = mBlendingOptions.GetBlendDestFactorRgb();
206   srcFactorAlpha  = mBlendingOptions.GetBlendSrcFactorAlpha();
207   destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
208 }
209
210 void ImageAttachment::SetBlendEquation( BlendingEquation::Type equationRgb, BlendingEquation::Type equationAlpha )
211 {
212   mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
213
214   // attachment is being used in a separate thread; queue a message to set the value
215   SetBlendingOptionsMessage( GetEventThreadServices(), GetSceneObject(), mBlendingOptions.GetBitmask() );
216 }
217
218 void ImageAttachment::GetBlendEquation( BlendingEquation::Type& equationRgb, BlendingEquation::Type& equationAlpha ) const
219 {
220   // These are not animatable, the cached values are up-to-date.
221   equationRgb   = mBlendingOptions.GetBlendEquationRgb();
222   equationAlpha = mBlendingOptions.GetBlendEquationAlpha();
223 }
224
225 void ImageAttachment::SetBlendColor( const Vector4& color )
226 {
227   if( mBlendingOptions.SetBlendColor( color ) )
228   {
229     // attachment is being used in a separate thread; queue a message to set the value
230     SetBlendColorMessage( GetEventThreadServices(), GetSceneObject(), color );
231   }
232 }
233
234 const Vector4& ImageAttachment::GetBlendColor() const
235 {
236   const Vector4* optionalColor = mBlendingOptions.GetBlendColor();
237   if( optionalColor )
238   {
239     return *optionalColor;
240   }
241
242   return Vector4::ZERO;
243 }
244
245 void ImageAttachment::SetFilterMode( FilterMode::Type minFilter, FilterMode::Type magFilter )
246 {
247   mSamplerBitfield = ImageSampler::PackBitfield( minFilter, magFilter );
248
249   SetSamplerMessage( GetEventThreadServices(), GetSceneObject(), mSamplerBitfield );
250 }
251
252 void ImageAttachment::GetFilterMode( FilterMode::Type& minFilter, FilterMode::Type& magFilter ) const
253 {
254   minFilter = ImageSampler::GetMinifyFilterMode( mSamplerBitfield );
255   magFilter = ImageSampler::GetMagnifyFilterMode( mSamplerBitfield );
256 }
257
258
259 void ImageAttachment::SetShaderEffect(ShaderEffect& effect)
260 {
261   if ( OnStage() )
262   {
263     if ( mShaderEffect )
264     {
265       mShaderEffect->Disconnect();
266     }
267
268     mShaderEffect.Reset( &effect );
269
270     const SceneGraph::Shader& shader = dynamic_cast<const SceneGraph::Shader&>( *mShaderEffect->GetSceneObject() );
271
272     ApplyShaderMessage( GetEventThreadServices(), GetSceneObject(), shader );
273
274     mShaderEffect->Connect();
275   }
276   else
277   {
278     mShaderEffect = ShaderEffectPtr(&effect);
279   }
280   // Effects can only be applied when the Node is connected to scene-graph
281 }
282
283 ShaderEffectPtr ImageAttachment::GetShaderEffect() const
284 {
285   return mShaderEffect;
286 }
287
288 void ImageAttachment::RemoveShaderEffect()
289 {
290   if ( OnStage() )
291   {
292     RemoveShaderMessage( GetEventThreadServices(), GetSceneObject() );
293
294     // Notify shader effect
295     if (mShaderEffect)
296     {
297       mShaderEffect->Disconnect();
298     }
299   }
300
301   mShaderEffect.Reset();
302 }
303
304
305 void ImageAttachment::OnStageConnection2()
306 {
307   if ( mShaderEffect )
308   {
309     const SceneGraph::Shader& shader = dynamic_cast<const SceneGraph::Shader&>( *mShaderEffect->GetSceneObject() );
310
311     ApplyShaderMessage( GetEventThreadServices(), GetSceneObject(), shader );
312
313     // Notify shader effect
314     mShaderEffect->Connect();
315   }
316
317   mImageConnectable.OnStageConnect();
318
319   // Provide resource ID when scene-graph attachment is connected
320   ImagePtr image = mImageConnectable.Get();
321   unsigned int resourceId = (image) ? image->GetResourceId() : 0u;
322   if ( 0u != resourceId )
323   {
324     SetTextureIdMessage( GetEventThreadServices(), *mSceneObject, resourceId );
325   }
326 }
327
328 void ImageAttachment::OnStageDisconnection2()
329 {
330   // Notify shader effect
331   if ( mShaderEffect )
332   {
333     mShaderEffect->Disconnect();
334   }
335
336   // Remove resource ID when scene-graph attachment is disconnected
337   SetTextureIdMessage( GetEventThreadServices(), *mSceneObject, 0u );
338
339   mImageConnectable.OnStageDisconnect();
340 }
341
342
343
344 } // namespace Internal
345
346 } // namespace Dali